Casos de Uso

coleta autorizada de pesquisa acadêmica com resolução de CAPTCHA

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


Acelere sua revisão da literatura -obtenha sua chave CaptchaAIe automatizar a coleta de dados acadêmicos.

Os comentários estão desativados para este artigo.