Quantos CAPTCHAs uma coleta de pesquisa de mercado encontra pela frente? Entre 20% e 40% das páginas de fontes típicas — sites de avaliação, vagas, diretórios e bases de patentes — usam reCAPTCHA, Turnstile ou CAPTCHA de imagem para conter bots, e cada desafio sem tratamento automatizado trava o pipeline até alguém resolver manualmente. Este guia mostra como montar em Python um coletor que detecta o tipo de desafio e resolve via API da CaptchaAI, sem intervenção manual e sem reescrever o scraper toda vez que uma fonte muda de proteção.
Na prática: cerca de 30% das páginas de pesquisa de mercado acionam algum CAPTCHA. Em 1.000 páginas/dia, isso representa por volta de 300 resoluções — custo total estimado entre US$ 0,5 e US$ 3, tranquilamente dentro do plano BASIC (US$ 15/mês, 5 threads).
Onde a pesquisa de mercado esbarra em CAPTCHA
| Tipo de fonte | Exemplos | Tipo de CAPTCHA |
|---|---|---|
| Sites de avaliação | G2, Trustpilot, Yelp | reCAPTCHA v2/v3 |
| Quadros de vagas | LinkedIn, Indeed | Cloudflare Challenge |
| Diretórios de empresas | Páginas Amarelas, Crunchbase | Cloudflare Turnstile, reCAPTCHA |
| Redes sociais | Twitter/X, Reddit | Vários tipos |
| Bases de patentes | USPTO, Google Patents | reCAPTCHA v2 |
| Dados governamentais | Arquivos da SEC, censo | CAPTCHA de imagem |
A coluna da direita já indica o parâmetro que o coletor precisa enviar: reCAPTCHA usa googlekey e pageurl; Turnstile usa sitekey. É essa detecção por regex que o pipeline abaixo automatiza, sem precisar mapear manualmente cada fonte antes de rodar a coleta.
Um pipeline em Python que resolve CAPTCHA automaticamente
O coletor abaixo faz três coisas: busca a página, detecta se apareceu reCAPTCHA ou Turnstile e, se apareceu, resolve com a CaptchaAI antes de reenviar a requisição.
import requests
import time
import re
import csv
import os
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
def solve_captcha(params):
params["key"] = API_KEY
resp = requests.get("https://ocr.captchaai.com/in.php", params=params)
if not resp.text.startswith("OK|"):
raise Exception(f"Submit: {resp.text}")
task_id = resp.text.split("|")[1]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id,
})
if result.text == "CAPCHA_NOT_READY":
continue
if result.text.startswith("OK|"):
return result.text.split("|", 1)[1]
raise Exception(f"Solve: {result.text}")
raise TimeoutError()
class MarketResearchCollector:
def __init__(self):
self.session = requests.Session()
self.session.headers["User-Agent"] = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/120.0.0.0"
)
def fetch(self, url):
"""Fetch a page, solving CAPTCHAs as needed."""
resp = self.session.get(url)
# Detect reCAPTCHA
match = re.search(
r'data-sitekey=["\']([A-Za-z0-9_-]+)["\']', resp.text
)
if match:
token = solve_captcha({
"method": "userrecaptcha",
"googlekey": match.group(1),
"pageurl": url,
})
resp = self.session.post(url, data={
"g-recaptcha-response": token,
})
# Detect Turnstile
match = re.search(
r'data-sitekey=["\']([0-9x][A-Za-z0-9_-]+)["\']', resp.text
)
if match and "cf-turnstile" in resp.text:
token = solve_captcha({
"method": "turnstile",
"sitekey": match.group(1),
"pageurl": url,
})
resp = self.session.post(url, data={
"cf-turnstile-response": token,
})
return resp.text
def collect_reviews(self, urls):
"""Collect review data from multiple pages."""
reviews = []
for url in urls:
try:
html = self.fetch(url)
page_reviews = self._parse_reviews(html)
reviews.extend(page_reviews)
print(f" Collected {len(page_reviews)} reviews from {url}")
time.sleep(2) # Polite delay
except Exception as e:
print(f" Error on {url}: {e}")
return reviews
def collect_company_profiles(self, urls):
"""Collect company profile data."""
profiles = []
for url in urls:
try:
html = self.fetch(url)
profile = self._parse_profile(html)
if profile:
profiles.append(profile)
print(f" Collected: {profile.get('name', 'Unknown')}")
time.sleep(2)
except Exception as e:
print(f" Error on {url}: {e}")
return profiles
def _parse_reviews(self, html):
"""Extract review data from HTML."""
reviews = []
# Generic review extraction patterns
for match in re.finditer(
r'class="review-text"[^>]*>(.*?)</div>', html, re.DOTALL
):
reviews.append({
"text": match.group(1).strip()[:500],
})
return reviews
def _parse_profile(self, html):
"""Extract company profile from HTML."""
name = re.search(r'<h1[^>]*>(.*?)</h1>', html)
desc = re.search(
r'class="description"[^>]*>(.*?)</div>', html, re.DOTALL
)
return {
"name": name.group(1).strip() if name else None,
"description": desc.group(1).strip()[:300] if desc else None,
}
def export_csv(self, data, filename):
"""Export collected data to CSV."""
if not data:
return
keys = data[0].keys()
with open(filename, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=keys)
writer.writeheader()
writer.writerows(data)
print(f"Exported {len(data)} records to {filename}")
Como usar o coletor
collector = MarketResearchCollector()
# Collect competitor reviews
review_urls = [
"https://example-reviews.com/product/competitor-a",
"https://example-reviews.com/product/competitor-b",
"https://example-reviews.com/product/competitor-c",
]
reviews = collector.collect_reviews(review_urls)
collector.export_csv(reviews, "competitor_reviews.csv")
# Collect company profiles
profile_urls = [
"https://example-directory.com/company/alpha-corp",
"https://example-directory.com/company/beta-inc",
]
profiles = collector.collect_company_profiles(profile_urls)
collector.export_csv(profiles, "company_profiles.csv")
Casos de uso para pesquisa de mercado com CaptchaAI
- Monitoramento de preços da concorrência — acompanhe preços, promoções e estoque de concorrentes em marketplaces e e-commerces, com histórico suficiente para enxergar padrão sazonal.
- Sentimento de marca em avaliações — colete avaliações de plataformas como G2 ou Trustpilot e cruze o sentimento entre várias fontes para achar onde a marca perde pontos.
- Tendências do mercado de trabalho — extraia vagas publicadas para medir demanda por habilidades, faixas salariais praticadas e ritmo de contratação no seu setor.
- Panorama de patentes — reúna registros de bases públicas de patentes para acompanhar tendências de inovação e o P&D dos concorrentes ao longo do tempo.
- Monitoramento de redes sociais — acompanhe menções à marca e aos concorrentes no Twitter/X e no Reddit para captar sinais de reputação antes que virem crise.
Boas práticas para escalar a coleta
Antes de rodar isso em produção, ajuste estes cinco pontos:
- Espaçamento entre requisições: 2 a 5 segundos entre páginas — evita picos de tráfego que chamam atenção do WAF.
- Coletores simultâneos: 5 a 10 para escala moderada, subindo aos poucos conforme a fonte responder bem.
- Rotação de proxy: necessária acima de 100 páginas/hora, para não concentrar todo o volume em um único IP.
- Deduplicação de dados: gere um hash do conteúdo antes de gravar, para não reprocessar CAPTCHA em páginas já coletadas.
- Agendamento: rode diariamente ou semanalmente para captar tendências sem sobrecarregar as fontes em horário de pico.
Rodando a coleta a partir do Brasil
Se o time de BI está no Brasil mas as fontes ficam nos EUA ou na Europa, hospedar os workers perto do time — por exemplo em sa-east-1, São Paulo — reduz a latência do pipeline interno (fila, banco de dados, dashboards), mas não muda o RTT até o site de origem. Na prática, o tempo de resolução do CAPTCHA em si pesa menos no total do que essa latência de rede transatlântica, então não vale a pena otimizar o solver antes de otimizar a proximidade da infraestrutura da fonte. Veja também nosso guia de scraping sem bloqueio.
Perguntas frequentes sobre coleta de dados com CAPTCHA
Coletar dados públicos para pesquisa de mercado é permitido?
Na maioria dos casos, sim — dados públicos e não pessoais costumam ser aceitos. Confira sempre os termos de uso do site-fonte e evite salvar dados pessoais (nomes, e-mails, telefones) sem base legal na LGPD, ou na RGPD se a fonte estiver na Europa. Quando existir API oficial da fonte, prefira usá-la em vez do scraper — é mais estável e reduz o risco de bloqueio.
Preciso de proxy pago para rodar essa coleta em volume?
Acima de 100 páginas/hora, sim — combine rotação de proxy com o intervalo de 2 a 5 segundos entre páginas das boas práticas acima. Abaixo disso, muitas fontes toleram um único IP com espaçamento razoável, mas monitore a taxa de erro para saber quando migrar.
Quanto tempo leva para colocar esse pipeline no ar?
Com a chave de API em mãos, o esqueleto deste guia roda em poucas horas — o trabalho maior é mapear os seletores de cada site-fonte, não a parte de CAPTCHA, que já vem pronta no código acima.
É verdade que o CaptchaAI não resolve hCaptcha?
Sim, é verdade — nem o FunCaptcha (Arkose Labs) é suportado hoje. Para fontes com esses dois tipos, planeje uma alternativa: API oficial da fonte ou parceria de dados, em vez de tentar automatizar o desafio.
Como evito coletar registros duplicados na coleta diária?
Gere um hash (ex.: SHA-256) do conteúdo de cada registro e compare com o que já foi salvo antes de gravar. Isso evita reprocessar CAPTCHA em páginas que a coleta já visitou no dia anterior.
Guias relacionados
- Monitoramento de preços no e-commerce
- CAPTCHA em fluxos de coleta autorizada
- Rotação de proxy para scraping