Comment éviter les captchas lors du scraping (sans enfreindre les règles)
La plupart des captchas rencontrés pendant le scraping sont une réaction à un trafic qui paraît automatisé. Le moyen le moins coûteux de s'en sortir est de cesser de les déclencher. Cela signifie chercher d'abord une source de données légitime, vérifier ce que les règles du site autorisent, envoyer moins de requêtes et plus lentement, et ne pas récupérer deux fois la même page. Résoudre un captcha est la solution de repli pour les cas que vous ne pouvez pas éviter, pas le plan de départ.
Vérifiez d'abord s'il existe une API ou un flux officiel
Beaucoup de sites qui sont scrapés proposent déjà un moyen d'obtenir les mêmes données sans captcha : une API publique, un export de données, un flux RSS ou sitemap, ou un programme partenaire. Une source officielle est plus fiable, moins susceptible de changer sans préavis et donne au propriétaire du site un droit de regard sur votre usage. Cherchez :
- une section développeurs ou API dans le pied de page du site,
- un
sitemap.xmlqui liste les pages, - des liens RSS ou Atom dans le
<head>de la page, - une page « données » ou « téléchargement » pour les exports en masse.
Si l'une de ces options couvre votre besoin, utilisez-la. Vous éviterez la plupart des captchas en ne demandant tout simplement pas de HTML.
Respectez le robots.txt et le délai qu'il demande
robots.txt indique quels chemins les clients automatisés ont le droit de récupérer et, parfois, combien de temps attendre entre deux requêtes. La bibliothèque standard de Python peut le lire pour vous :
import time
from urllib.robotparser import RobotFileParser
import requests
USER_AGENT = "ExampleBot/1.0 (+https://example.com/bot)"
parser = RobotFileParser()
parser.set_url("https://example.com/robots.txt")
parser.read()
delay = parser.crawl_delay(USER_AGENT) or 5 # repli prudent de 5 secondes
urls = [
"https://example.com/products?page=1",
"https://example.com/products?page=2",
]
last_request = 0.0
for url in urls:
if not parser.can_fetch(USER_AGENT, url):
print("skipped by robots.txt:", url)
continue
wait = delay - (time.monotonic() - last_request)
if wait > 0:
time.sleep(wait)
resp = requests.get(url, headers={"User-Agent": USER_AGENT}, timeout=30)
last_request = time.monotonic()
print(url, resp.status_code)
Si robots.txt interdit un chemin, la réponse honnête est de le laisser tranquille ou de demander au propriétaire. Contourner cette interdiction avec un navigateur ne change pas ce que le site a demandé.
Ralentissez et répartissez les requêtes
Un rythme régulier et modéré déclenche rarement un défi, alors qu'une rafale le déclenche presque toujours. Quelques habitudes font une grande différence :
- Choisissez un rythme de requêtes par site et tenez-vous-y, au lieu d'aller à pleine vitesse.
- Ajoutez une gigue aléatoire pour que le rythme ne soit pas parfaitement régulier.
- Arrêtez-vous et patientez un moment lorsque vous voyez un 429 ou une page captcha.
- Lancez les travaux aux heures creuses si la charge du site est une préoccupation.
Mettez en cache et ne récupérez pas deux fois
Chaque requête que vous ne faites pas est une requête que le site n'a pas à traiter. Stockez les pages récupérées avec leur date et un hash de leur contenu, et ne les récupérez à nouveau que lorsque le contenu a probablement changé. Les requêtes conditionnelles avec les en-têtes If-Modified-Since ou ETag permettent au serveur de répondre « non modifié » à moindre coût lorsqu'il les prend en charge.
Réutilisez les sessions, envoyez des en-têtes ordinaires
Une session qui conserve les cookies entre les requêtes se comporte davantage comme un visiteur qu'un script qui repart de zéro à chaque fois. Utilisez requests.Session() pour chaque site, et envoyez un User-Agent clair et honnête qui indique le nom de votre bot et un contact. Ne vous faites pas passer pour un navigateur pour contourner une règle. Si un site a besoin de JavaScript pour afficher son contenu, utilisez un outil de navigateur pour ces pages, et gardez les mêmes limites de débit.
Lorsqu'un captcha apparaît quand même
Certains sites afficheront un captcha quel que soit votre niveau de prudence. Détectez-le dans votre code et arrêtez ce travail plutôt que de marteler la page. La détection et la résolution optionnelle pour PopularCaptcha sont expliquées dans les captchas du web scraping.
Planifiez le crawl avant de commencer
Un crawl qui récupère tout chaque jour est le moyen le plus simple de déclencher un captcha. Planifiez le travail d'abord :
- Priorisez. Décidez quelles pages changent souvent et lesquelles rarement. Explorez les pages fréquentes souvent, et les autres rarement.
- Utilisez les dates du sitemap. Beaucoup de sitemaps incluent une valeur
lastmod. Ignorez les URL qui n'ont pas changé depuis votre dernière visite. - Crawlez de façon incrémentale. Stockez la dernière récupération réussie pour chaque URL, et reprenez à partir de là au lieu de tout recommencer depuis la première page après un échec.
- Répartissez la charge. Découpez une grande liste en lots et exécutez-les au fil de la journée, pas tous en même temps.
Un plan de ce type réduit le nombre de requêtes, et c'est le levier le plus important que vous ayez.
Consignez le plan dans un petit fichier de configuration ou un tableau : les sites, les sections, l'intervalle de rafraîchissement et le budget de requêtes quotidien pour chacun. Lorsque le budget est épuisé, le travail s'arrête jusqu'à la fenêtre suivante. Traiter le budget comme une limite stricte, et non comme une simple recommandation, est ce qui empêche un crawler de glisser vers le schéma de trafic qui déclenche les captchas. Revoyez le budget toutes les quelques semaines, car un site qui grandit peut aussi voir son trafic augmenter, et ce qui était poli le trimestre dernier ne l'est peut-être plus aujourd'hui.
Scrapez de manière responsable
- Consultez le
robots.txtet les conditions d'utilisation avant de commencer, et respectez ce qu'ils disent. - Gardez un rythme de requêtes faible et arrêtez-vous lorsque le site signale qu'il peine.
- Ne collectez pas de données personnelles dont vous n'avez aucune raison de disposer, et supprimez-les lorsque vous n'en avez plus besoin.
- Ne republiez pas en masse du contenu protégé par le droit d'auteur. Utilisez les données pour l'analyse, la comparaison ou votre propre produit, et citez la source lorsque c'est approprié.
- Contactez le propriétaire du site si vous avez besoin d'un volume plus important. Il peut proposer un flux.