Captchas bij webscraping: waarom ze verschijnen en wat je kunt doen
Een captcha verschijnt tijdens scraping wanneer een site besluit dat een verzoek geautomatiseerd lijkt. De gebruikelijke triggers zijn te veel requests in korte tijd, een IP-adres met een slechte reputatie, ontbrekende browsersignalen, of een treffer op een pagina die de site strenger beschermt dan de rest. De praktische aanpak heeft drie stappen, in deze volgorde: de triggers verminderen, de captcha in code detecteren, en de captcha oplossen die je niet kunt vermijden. Deze gids behandelt elke stap en verwijst naar de gedetailleerde gidsen voor de rest.
Waarom sites captchas tonen aan scrapers
Een site heeft weinig manieren om op het moment van een paginaverzoek een persoon van een script te onderscheiden, dus kijkt hij naar patronen. Een scraper valt vaak op doordat hij:
- requests verstuurt sneller dan welke persoon ook zou klikken,
- steeds hetzelfde pad herhaalt zonder pauze,
- vanaf een datacenteradres komt in plaats van een thuisnetwerk,
- headers stuurt die niet overeenkomen met een gangbare browser, of
- geen cookies of sessiestatus tussen requests bewaart.
Elk van die kan voldoende zijn. De captcha is de manier van de site om om een menselijke stap te vragen voordat hij meer pagina's serveert. Het patroon verkleinen vermindert meestal de captchas, en dat is goedkoper dan ze oplossen.
Detecteer de captcha in code
Controleer voordat je iets oplost of de pagina die je kreeg wel de captchapagina is. Een eenvoudige test zoekt naar de widgetopmaak en leest de sitekey:
import re
import requests
SITEKEY_RE = re.compile(r'data-sitekey="([0-9a-f-]{36})"')
def fetch(url: str) -> dict:
resp = requests.get(
url,
timeout=30,
headers={"User-Agent": "ExampleBot/1.0 (+https://example.com/bot)"},
)
html = resp.text
if "h-captcha" in html or "g-recaptcha" in html:
match = SITEKEY_RE.search(html)
return {"captcha": True, "sitekey": match.group(1) if match else None, "html": html}
return {"captcha": False, "sitekey": None, "html": html}
page = fetch("https://example.com/search?q=shoes")
if page["captcha"]:
print("captcha gevonden, sitekey:", page["sitekey"])
De strings h-captcha en g-recaptcha zijn alleen de opmaak die een pagina gebruikt, dus dit is een signaal en geen garantie. Ontbreekt de sitekey, zie hoe je een captcha-sitekey vindt.
Los hem op wanneer je er niet omheen kunt
Wanneer een PopularCaptcha-widget op de pagina staat en je de sitekey hebt, kun je met één POST-verzoek een token bij de Scarnox-API aanvragen en het indienen in het veld h-captcha-response. De volledige functie, met foutafhandeling, staat in een captcha oplossen vanuit Python met één verzoek. Gebruik het token meteen, want het verloopt na ongeveer twee minuten. De details over timing staan in verlopen captchatoken.
De live ondersteuning van Scarnox is vandaag PopularCaptcha, proxyless en met je eigen proxy. reCAPTCHA v2 en v3, Cloudflare Turnstile, GeeTest, AWS WAF en Arkose komen binnenkort beschikbaar. Als je doel een van die gebruikt, leggen de captchagidsen de algemene opties uit, maar bouw nog geen productieflow op een solve die niet live is.
Een beslissingsvolgorde voor elke geblokkeerde pagina
Wanneer je scraper een captcha tegenkomt, houdt een eenvoudige beslissingsvolgorde de taak eerlijk en het aantal requests laag:
- Is er een databron die je in plaats daarvan kunt gebruiken? Als een API, feed of export de velden dekt die je nodig hebt, schakel dan daarop over en vraag die pagina niet meer op.
- **Staat het pad in
robots.txttoe?** Zo niet, sla het over. Los geen captcha op een pagina waarvan je is gevraagd die met rust te laten. - Heb je te veel en te snel gestuurd? Pauzeer langer, verlaag je frequentie en controleer later opnieuw. Veel captchas verdwijnen bij een rustiger tempo.
- Is de captcha een live type? Als het PopularCaptcha is, geldt de solve in deze gids. Als het een type is dat binnenkort komt, houd de taak dan gepauzeerd en houd de release in de gaten.
- Is de pagina een pagina die je mag automatiseren? Als het antwoord onduidelijk is, vraag de eigenaar van de site dan voordat je verdergaat.
De vierde stap wordt het vaakst overgeslagen. Een solver is alleen nuttig wanneer het captchatype wordt ondersteund, en een taak die een niet-ondersteund type opnieuw probeert, verspilt tijd en requests.
Behandel de captcha in een taak, niet in een lus
Zet de solve in het codepad dat het token nodig heeft, zodat de taak elke captcha kan loggen, stopt wanneer een pagina steeds faalt, en doorgaat. Een onbegrensde lus die steeds een captchapagina opvraagt, is de snelste manier om de firewall van een site je adres voorgoed te laten blokkeren.
Houd bij wat faalt
Hou een teller bij van pagina's die een captcha teruggeven, gegroepeerd op URL en op tijdstip van de dag. Een captcha die alleen op één sectie van een site verschijnt, of alleen na een bepaald aantal requests, vertelt je waar de trigger zit. Die informatie is nuttiger dan een snellere solver, omdat ze je laat zien wat je moet veranderen.
Wat je niet moet doen
- Gebruik niet tientallen IP-adressen om de limieten van een site te omzeilen. Dat is ontwijking, en het verandert een verzoek om te vertragen in een gevecht.
- Scrape geen pagina's achter een login met inloggegevens waarvoor je niet bent gemachtigd.
- Los geen captchas op om accounts aan te maken, spam te plaatsen of beperkte artikelen te kopen.
Scrape verantwoord
- Lees het
robots.txt-bestand en de gebruiksvoorwaarden van de site voordat je begint. Respecteer de uitgesloten paden en elke crawl-vertraging. - Identificeer je bot eerlijk in de User-Agent, met een manier om je te bereiken.
- Houd de aanvraagfrequentie laag. Een captcha is vaak de site die je vraagt langzamer te gaan.
- Stop als de site je dat vraagt, en omzeil geen blokkade waarvan je is gezegd die te respecteren.
- Behandel persoonsgegevens volgens de privacyregels die voor jou gelden, en verzamel alleen wat je nodig hebt.