Un CAPTCHA qui surgit au milieu d'une revue de littérature n'arrête pas votre accès aux données publiques : il arrête seulement votre script. La bonne réponse tient en trois gestes — détecter le défi dans la page renvoyée, le résoudre via l'API CaptchaAI, puis resoumettre la requête avec le token obtenu. Sur Google Scholar, PubMed, Web of Science ou Scopus, cette boucle garde un workflow de bibliométrie ou de veille scientifique stable, à condition de respecter les conditions d'accès de chaque plateforme et de privilégier les API officielles.
Sur quelles plateformes académiques le CAPTCHA se déclenche-t-il ?
| Source | Type de vérification | Déclencheur | Données visées |
|---|---|---|---|
| Google Scholar | reCAPTCHA v3 | Volume élevé de requêtes et navigation rapide | Citations, références, résultats de recherche |
| PubMed | reCAPTCHA v2 | Requêtes répétées ou extraction trop rapide | Littérature biomédicale |
| Web of Science | Cloudflare Turnstile | Exports en masse ou consultation soutenue | Métriques de citation |
| Scopus | reCAPTCHA v2 | Multiplication des exports | Données bibliométriques |
| IEEE Xplore | reCAPTCHA v2 | Recherche suivie de nombreux accès pages | Articles d'ingénierie |
| JSTOR | reCAPTCHA v2 | Parcours répétitif des pages de contenu | Sciences humaines et sociales |
Ces plateformes s'appuient très majoritairement sur des types que CaptchaAI prend en charge : reCAPTCHA v2, reCAPTCHA v3 et Cloudflare Turnstile. L'objectif reste de fiabiliser une collecte autorisée quand un défi s'intercale au milieu du processus. Si une source déploie hCaptcha ou FunCaptcha, sachez qu'ils ne sont pas pris en charge : vérifiez le type de défi avant d'y brancher votre pipeline.
Scénario : une équipe de bibliométrie en contexte RGPD
Une équipe de recherche francophone qui prépare une revue systématique a besoin des titres, DOI, auteurs et compteurs de citations, pas de données personnelles. Deux réflexes rendent la collecte durable :
- Sobriété des données : ne collecter que le nécessaire, documenter finalité et conservation, vérifier ses obligations RGPD dès qu'un champ identifiant apparaît ;
- Sobriété du débit : une collecte peu concurrente suffit — un plan BASIC ($15/mois, 5 threads) couvre déjà ce volume, chaque thread traitant un CAPTCHA à la fois.
Cadence de requêtes : des délais prudents par source
| Source | Délai recommandé | Volume indicatif maximal par heure |
|---|---|---|
| Google Scholar | 10-15 secondes | 40-50 pages |
| PubMed | 3-5 secondes | 100 pages |
| Web of Science | 5-10 secondes | 60 pages |
| Scopus | 5-10 secondes | 60 pages |
| IEEE Xplore | 3-5 secondes | 100 pages |
| JSTOR | 5-10 secondes | 60 pages |
Ces valeurs sont indicatives et varient selon la source, le volume et le moment de la journée. Les plateformes académiques réagissent vite à un trafic trop régulier ou trop dense : des délais prudents, une rotation de proxys résidentiels au besoin et l'usage prioritaire des interfaces officielles donnent de meilleurs résultats qu'une accélération agressive.
Exemple : un collecteur de citations en Python
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")
Ce squelette réunit les réflexes d'un collecteur robuste :
- une session HTTP réutilisée d'une requête à l'autre ;
- une détection explicite du CAPTCHA avant tout parsing ;
- une nouvelle soumission après résolution du token ;
- une extraction propre des métadonnées, sans confondre page de défi et page de résultats.
Construire un graphe de citations
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
Un réseau de citations ne se lit pas sur la première page de résultats. Il faut suivre les liens « cité par », borner la profondeur et la largeur d'exploration, et garder un délai fixe entre les requêtes. Un parallélisme trop agressif fait grimper le risque de CAPTCHA ou de blocage IP bien plus vite qu'il n'accélère la collecte ; limiter la largeur à quelques citations par nœud garde le graphe exploitable.
Résoudre les blocages courants
Les symptômes les plus fréquents et la première action à tenter.
| Problème | Cause probable | Action recommandée |
|---|---|---|
| Un CAPTCHA apparaît à chaque recherche | L'adresse IP est jugée risquée | Changez de proxy, portez le délai à 15 secondes ou plus et réduisez la concurrence |
| Aucun résultat extrait alors que la requête aboutit | La page de défi a remplacé la page de résultats | Détectez le CAPTCHA avant le parsing ; ne supposez jamais qu'une réponse HTML contient la liste attendue |
| Résumé ou métadonnées absents | Contenu derrière un paywall ou réservé à un accès institutionnel | Passez par un accès autorisé ou une source ouverte, sans dépendre du seul HTML public |
| Google Scholar bloque l'IP | Rythme de requête trop élevé | Faites une pause, changez d'IP et baissez la densité de recherche |
| Export ou téléchargement plafonné | La plateforme limite les extractions par lot | Découpez le travail en petits lots et gardez des points de reprise |
FAQ
Les questions qui reviennent le plus souvent sur ce type de collecte.
CaptchaAI prend-il en charge les CAPTCHA des plateformes académiques ?
Oui pour les types les plus fréquents sur ces sites : reCAPTCHA v2, reCAPTCHA v3 et Cloudflare Turnstile sont pris en charge. En revanche, hCaptcha et FunCaptcha ne le sont pas — si une source les utilise, l'API ne pourra pas les résoudre. Identifiez le type de défi avant d'intégrer la source à votre pipeline.
Vaut-il mieux passer par une API officielle quand elle existe ?
Oui. PubMed expose par exemple E-utilities, et plusieurs éditeurs proposent des API de métadonnées. Une interface officielle est plus stable, mieux documentée et déclenche rarement un CAPTCHA. Réservez le scraping aux sources sans API publique.
Comment rester conforme au RGPD lors de la collecte ?
Collectez le minimum utile : pour la bibliométrie, les titres, DOI, auteurs et compteurs de citations suffisent, sans données personnelles superflues. Documentez la finalité, la durée de conservation et la base légale, et vérifiez vos obligations auprès de la CNIL dès qu'un champ identifiant est concerné.
Un proxy institutionnel fonctionne-t-il avec CaptchaAI ?
Oui, les deux couches sont indépendantes. Votre session passe par le proxy institutionnel, tandis que CaptchaAI se contente de résoudre le défi renvoyé. Gardez une cohérence entre cookies, en-têtes et adresse IP pour éviter que les défis ne se répètent.
Guides connexes
- La rotation des proxys résidentiels
- Réduire les interruptions CAPTCHA dans le scraping web
Fiabilisez votre collecte de recherche : créez votre compte CaptchaAI et automatisez la résolution des CAPTCHA sans fragiliser votre pipeline.