Use Cases

Веб-скрапинг академических исследований с решением CAPTCHA

Академические базы данных и журнальные порталы используют CAPTCHA для ограничения автоматического доступа. Исследователи, проводящие обзоры литературы, библиометрический анализ и мета-исследования, должны собирать данные из этих источников в больших масштабах. CaptchaAI автоматически решает задачи CAPTCHA.


Академические источники и CAPTCHA

Источник Тип капчи Курок Данные
Google Академика reCAPTCHA v3 Большие объемы запросов Цитаты, статьи
ПабМед reCAPTCHA v2 Повторные поиски Биомедицинская литература
Сеть науки Cloudflare Turnstile Массовые загрузки Метрики цитирования
Скопус reCAPTCHA v2 Экспортные операции Библиометрические данные
IEEE исследование reCAPTCHA v2 Поиск + скачать Инженерная документация
ДЖСТОР reCAPTCHA v2 Доступ к страницам Гуманитарные науки/social наука

Сборщик данных цитирования

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")

Библиометрический анализ

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

Ограничение скорости для академических сайтов

Источник Рекомендуемая задержка Макс. страниц/Hour
Google Академика 10-15 секунд 40-50
ПабМед 3-5 секунд 100
Сеть науки 5-10 секунд 60
Скопус 5-10 секунд 60
IEEE 3-5 секунд 100
ДЖСТОР 5-10 секунд 60

Академические сайты быстро блокируют IP-адреса. Используйте консервативные задержки.


Поиск неисправностей

Проблема Причина Исправить
CAPTCHA при каждом поиске Академический сайт пометил IP-адрес Переключить прокси, увеличить задержку до 15+ секунд
Результаты не возвращены Вместо этого возвращена страница CAPTCHA Проверьте CAPTCHA перед парсингом
Аннотация отсутствует За платным доступом Используйте институциональный прокси или открытый доступ
Ученый блокирует IP Превышен лимит скорости Подождите 30 минут, используйте другой IP-адрес.
Экспорт ограничен Ограничения на массовые загрузки сайта Загружайте небольшими партиями

Часто задаваемые вопросы

Разрешено ли парсинг академических баз данных?

Публичные метаданные (названия, авторы, аннотации) обычно доступны. Полнотекстовый доступ зависит от лицензирования. PubMed явно поддерживает программный доступ через свой API электронных утилит. Всегда отдавайте предпочтение официальным API, если они доступны.

Как избежать блокировки в Google Scholar?

Используйте 10-15-секундные задержки между запросами, чередуйте авторизованный сетевой выход и ограничьте количество запросов до 50 в час. Ученый агрессивно относится к блокированию автоматического доступа.

Могу ли я использовать CaptchaAI с институциональным прокси?

Да. Установите свой институциональный прокси для сеанса просмотра и CaptchaAI для решения CAPTCHA — они работают независимо.


Связанные руководства

  • Ротация авторизованный сетевой выход
  • Качество прокси влияет на скорость решения

Ускорьте обзор литературы —получите ключ CaptchaAIи автоматизировать сбор академических данных.

Комментарии для этой статьи отключены.

Похожие сообщения

Tutorials Кеширование CAPTCHA-токенов в собственном backend в пределах TTL
Корректно кешируйте и переиспользуйте CAPTCHA-токены в пределах официального TTL для идемпотентных ретраев в собственном backend.

Корректно кешируйте и переиспользуйте CAPTCHA-токены в пределах официального TTL для идемпотентных ретраев в с...

May 02, 2026
Use Cases Тестирование CAPTCHA для e-commerce checkout с высокой нагрузкой
QA-руководство по проверке CAPTCHA в собственных checkout-сценариях e-commerce в staging: фиктивный инвентарь, тестовые платежные токены и Captcha AI.

QA-руководство по проверке CAPTCHA в собственных checkout-сценариях e-commerce в staging: фиктивный инвентарь,...

May 05, 2026
Use Cases Решение CAPTCHA для тестирования конечных точек API в веб-формах
Практическое руководство по решению CAPTCHA для тестирования конечных точек API в веб-формах с реалистичными сценариями, советами по рабочему процессу и практич...

Практическое руководство по решению CAPTCHA для тестирования конечных точек API в веб-формах с реалистичными с...

May 08, 2026