Bancos de dados acadêmicos e portais de periódicos usam CAPTCHAs para limitar o acesso automatizado. Os pesquisadores que realizam revisões de literatura, análises bibliométricas e metaestudos precisam coletar dados dessas fontes em grande escala. CaptchaAI lida com os desafios CAPTCHA automaticamente.
Fontes Acadêmicas e CAPTCHAs
| Fonte | Tipo CAPTCHA | Gatilho | Dados |
|---|---|---|---|
| Google Acadêmico | reCAPTCHA v3 | Consultas de alto volume | Citações, artigos |
| PubMed | reCAPTCHA v2 | Pesquisas repetidas | Literatura biomédica |
| Web da Ciência | Cloudflare Turnstile | Downloads em massa | Métricas de citação |
| Escopo | reCAPTCHA v2 | Operações de exportação | Dados bibliométricos |
| Explorar IEEE | reCAPTCHA v2 | Pesquisar + baixar | Artigos de engenharia |
| JSTOR | reCAPTCHA v2 | Acesse páginas | Humanidades/social ciência |
Coletor de dados de citação
import requests
import time
import re
from bs4 import BeautifulSoup
import csv
CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"
def solve_captcha(method, sitekey, pageurl, **kwargs):
data = {
"key": CAPTCHAAI_KEY, "method": method,
"googlekey": sitekey, "pageurl": pageurl, "json": 1,
}
data.update(kwargs)
resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data=data)
task_id = resp.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
"key": CAPTCHAAI_KEY, "action": "get",
"id": task_id, "json": 1,
})
r = result.json()
if r["request"] != "CAPCHA_NOT_READY":
return r["request"]
raise TimeoutError("Timeout")
class AcademicScraper:
def __init__(self, proxy=None):
self.session = requests.Session()
if proxy:
self.session.proxies = {"http": proxy, "https": proxy}
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
})
def search_papers(self, search_url, query, max_pages=10):
"""Search academic database for papers matching query."""
all_papers = []
for page in range(max_pages):
url = f"{search_url}?q={query}&start={page * 10}"
resp = self.session.get(url, timeout=30)
# Handle CAPTCHA
if self._has_captcha(resp.text):
resp = self._solve_and_retry(resp.text, url)
papers = self._parse_results(resp.text)
if not papers:
break # No more results
all_papers.extend(papers)
print(f"Page {page + 1}: {len(papers)} papers")
time.sleep(5) # Respectful delay
return all_papers
def get_paper_details(self, paper_url):
"""Get detailed metadata for a single paper."""
resp = self.session.get(paper_url, timeout=30)
if self._has_captcha(resp.text):
resp = self._solve_and_retry(resp.text, paper_url)
soup = BeautifulSoup(resp.text, "html.parser")
return {
"title": self._safe_text(soup, "h1, .article-title"),
"authors": self._safe_text(soup, ".authors, .author-list"),
"abstract": self._safe_text(soup, ".abstract, #abstract"),
"doi": self._safe_text(soup, ".doi, [data-doi]"),
"journal": self._safe_text(soup, ".journal-name, .publication"),
"year": self._safe_text(soup, ".pub-date, .year"),
"citations": self._safe_text(soup, ".citation-count, .cited-by"),
}
def export_to_csv(self, papers, filename):
"""Export collected papers to CSV."""
if not papers:
return
keys = papers[0].keys()
with open(filename, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=keys)
writer.writeheader()
writer.writerows(papers)
print(f"Exported {len(papers)} papers to {filename}")
def _has_captcha(self, html):
return any(tag in html.lower() for tag in [
'data-sitekey', 'g-recaptcha', 'cf-turnstile',
])
def _solve_and_retry(self, html, url):
match = re.search(r'data-sitekey="([^"]+)"', html)
if not match:
return self.session.get(url)
sitekey = match.group(1)
if 'cf-turnstile' in html:
token = solve_captcha("turnstile", sitekey, url)
return self.session.post(url, data={"cf-turnstile-response": token})
else:
token = solve_captcha("userrecaptcha", sitekey, url)
return self.session.post(url, data={"g-recaptcha-response": token})
def _parse_results(self, html):
soup = BeautifulSoup(html, "html.parser")
papers = []
for item in soup.select(".gs_r, .search-result, article.result"):
title_el = item.select_one("h3 a, .result-title a")
if title_el:
papers.append({
"title": title_el.get_text(strip=True),
"url": title_el.get("href", ""),
"snippet": self._safe_text(item, ".gs_rs, .abstract-snippet"),
"authors": self._safe_text(item, ".gs_a, .author-info"),
})
return papers
def _safe_text(self, soup, selector):
el = soup.select_one(selector)
return el.get_text(strip=True) if el else ""
# Usage — Literature review
scraper = AcademicScraper(
proxy="http://user:pass@residential.proxy.com:5000"
)
papers = scraper.search_papers(
"https://scholar.example.com/scholar",
query="machine learning CAPTCHA solving",
max_pages=5,
)
# Get details for top papers
detailed = []
for paper in papers[:20]:
if paper["url"]:
detail = scraper.get_paper_details(paper["url"])
detailed.append(detail)
time.sleep(3)
scraper.export_to_csv(detailed, "literature_review.csv")
Análise Bibliométrica
def bibliometric_analysis(scraper, seed_papers, depth=2):
"""Follow citations to build a citation network."""
visited = set()
network = []
def _crawl(paper_url, current_depth):
if current_depth > depth or paper_url in visited:
return
visited.add(paper_url)
try:
details = scraper.get_paper_details(paper_url)
network.append(details)
# Follow "cited by" links
resp = scraper.session.get(f"{paper_url}/citations", timeout=30)
if scraper._has_captcha(resp.text):
resp = scraper._solve_and_retry(resp.text, f"{paper_url}/citations")
citations = scraper._parse_results(resp.text)
for cite in citations[:5]: # Limit breadth
if cite["url"]:
_crawl(cite["url"], current_depth + 1)
time.sleep(3)
except Exception as e:
print(f"Error crawling {paper_url}: {e}")
for paper in seed_papers:
_crawl(paper["url"], 0)
return network
Limitação de taxa para sites acadêmicos
| Fonte | Atraso recomendado | Máximo de páginas/Hour |
|---|---|---|
| Google Acadêmico | 10-15 segundos | 40-50 |
| PubMed | 3-5 segundos | 100 |
| Web da Ciência | 5-10 segundos | 60 |
| Escopo | 5-10 segundos | 60 |
| IEEE | 3-5 segundos | 100 |
| JSTOR | 5-10 segundos | 60 |
Sites acadêmicos banem IPs rapidamente. Use atrasos conservadores.
Solução de problemas
| Problema | Causa | Correção |
|---|---|---|
| CAPTCHA em todas as pesquisas | IP sinalizado do site acadêmico | Alternar proxy, aumentar o atraso para mais de 15 segundos |
| Nenhum resultado retornado | Página CAPTCHA retornada | Verifique o CAPTCHA antes de analisar |
| Resumo faltando | Atrás do acesso pago | Use proxy institucional ou acesso aberto |
| Acadêmico bloqueia IP | Limite de taxa excedido | Aguarde 30 minutos, use IP diferente |
| Exportação limitada | Downloads em massa de limites de site | Baixe em lotes menores |
Perguntas frequentes
A raspagem de bancos de dados acadêmicos é permitida?
Os metadados públicos (títulos, autores, resumos) são geralmente acessíveis. O acesso ao texto completo depende do licenciamento. PubMed suporta explicitamente o acesso programático por meio de sua API E-utilities. Sempre prefira APIs oficiais quando disponíveis.
Como evito ser bloqueado no Google Acadêmico?
Use atrasos de 10 a 15 segundos entre as solicitações, alterne os proxies residenciais e limite a 50 consultas por hora. O Scholar é agressivo ao bloquear o acesso automatizado.
Posso usar CaptchaAI com procuração institucional?
Sim. Configure seu proxy institucional para a sessão de navegação e CaptchaAI para resolução de CAPTCHA – eles funcionam de forma independente.
Guias Relacionados
- Proxies residenciais rotativos
- A qualidade do proxy afeta a taxa de resolução
Acelere sua revisão da literatura -obtenha sua chave CaptchaAIe automatizar a coleta de dados acadêmicos.