Öffentliche Gesundheitsdaten stecken oft hinter einer Suchmaske mit reCAPTCHA v2 oder einem Bild-CAPTCHA – und genau an dieser Stelle bricht ein automatisierter Abruf ab. CaptchaAI löst diese Abfragen per API und liefert das fertige Token zurück, sodass Ihr Python-Scraper Anbieterverzeichnisse, Arzneimittelpreise und Studienregister ohne manuelles Eingreifen ausliest. Dieser Leitfaden zeigt, wo die CAPTCHAs auf Gesundheitsportalen auftauchen, wie Sie sie im Code lösen und welche rechtlichen Grenzen dabei gelten.
Wo Gesundheitsportale CAPTCHAs einsetzen
Nicht jede Seite schützt gleich stark. Bevor Sie einen Scraper aufsetzen, lohnt sich der Blick, welcher CAPTCHA-Typ an welcher Datenquelle sitzt – denn davon hängt die passende Lösungsmethode ab.
| Quelle | CAPTCHA-Typ | Daten | Anwendungsfall |
|---|---|---|---|
| Anbieterverzeichnisse (NPI) | Bild-CAPTCHA | Ärzte- und Einrichtungssuche | Netzabdeckung prüfen |
| Arzneimittelpreis-Portale | reCAPTCHA v2 | Medikamentenpreise | Preistransparenz |
| Register für klinische Studien | reCAPTCHA v2 | Studiendaten, Ergebnisse | Forschungsanalyse |
| Versicherungs-Formulare | reCAPTCHA v2 | Erstattungsfähige Präparate | Formularvergleich |
| Zulassungs- und Approbationsbehörden | Bild-CAPTCHA | Zulassungsprüfung | Nachweis der Qualifikation |
| Klinik-Qualitätsberichte | Cloudflare Turnstile | Qualitätskennzahlen | Leistungsvergleich |
reCAPTCHA v2 und Bild-CAPTCHAs decken damit den Großteil der Fälle ab. Cloudflare Turnstile taucht vor allem bei neueren Qualitätsportalen auf; CaptchaAI löst alle drei Typen über dieselbe API.
Gesundheitsdaten hinter CAPTCHA-Schutz im DACH-Raum
Die Codebeispiele in diesem Artikel orientieren sich an US-Portalen (NPI-Register, CMS-Preistransparenz), weil dort viele Datenquellen offen zugänglich sind. Das Muster überträgt sich aber direkt auf den deutschsprachigen Raum: Arztsuch-Portale der Kassenärztlichen Vereinigungen, Arzneimittel-Datenbanken wie die Gelbe Liste und das Deutsche Register Klinischer Studien (DRKS) folgen demselben Ablauf – Suchmaske aufrufen, CAPTCHA lösen, Formular absenden, Trefferliste parsen.
Ein Punkt verdient in der DACH-Region besondere Aufmerksamkeit: Sobald Sie über Proxys arbeiten, gelten IP-Adressen nach DSGVO als personenbezogene Daten. Prüfen Sie vor jedem größeren Lauf, welche Datenflüsse entstehen und auf welche Rechtsgrundlage Sie sich stützen. Das gilt als Sorgfaltspflicht auf Ihrer Seite – nicht als Compliance-Zusage von CaptchaAI. Beschränken Sie die Erfassung strikt auf öffentlich einsehbare, nicht patientenbezogene Informationen, dann bleiben Sie auf der sicheren Seite.
Anbieterverzeichnisse per Python-Scraper abrufen
Der folgende Collector kapselt beide Lösungswege in einer Klasse: solve_recaptcha für reCAPTCHA-v2-geschützte Preis- und Studienportale, solve_image_captcha für die klassischen Bild-CAPTCHAs der Arztverzeichnisse. Der Ablauf ist immer gleich – Suchseite laden, CAPTCHA lösen, Token oder Text ins Formular einfügen, Antwort parsen. Über batch_provider_lookup fahren Sie mehrere Fachrichtungen und Standorte in einem Durchlauf ab und schreiben die Treffer als CSV.
import requests
import time
import re
import base64
from bs4 import BeautifulSoup
import csv
CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"
def solve_recaptcha(sitekey, pageurl):
resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
"key": CAPTCHAAI_KEY, "method": "userrecaptcha",
"googlekey": sitekey, "pageurl": pageurl, "json": 1,
})
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,
})
data = result.json()
if data["request"] != "CAPCHA_NOT_READY":
return data["request"]
raise TimeoutError("Timeout")
def solve_image_captcha(image_bytes):
img_b64 = base64.b64encode(image_bytes).decode()
resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data={
"key": CAPTCHAAI_KEY, "method": "base64",
"body": img_b64, "json": 1,
})
task_id = resp.json()["request"]
for _ in range(20):
time.sleep(3)
result = requests.get(f"{CAPTCHAAI_URL}/res.php", params={
"key": CAPTCHAAI_KEY, "action": "get",
"id": task_id, "json": 1,
})
data = result.json()
if data["request"] != "CAPCHA_NOT_READY":
return data["request"]
raise TimeoutError("Timeout")
class HealthcareDataCollector:
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",
})
def search_providers(self, portal_url, specialty, location, sitekey=None):
"""Search provider directory with CAPTCHA handling."""
resp = self.session.get(portal_url, timeout=30)
data = {"specialty": specialty, "location": location}
# Handle CAPTCHA
if sitekey:
token = solve_recaptcha(sitekey, portal_url)
data["g-recaptcha-response"] = token
else:
captcha_img = re.search(r'src="(/captcha[^"]+)"', resp.text)
if captcha_img:
img_url = portal_url.rstrip("/") + captcha_img.group(1)
img = self.session.get(img_url)
data["captcha"] = solve_image_captcha(img.content)
resp = self.session.post(portal_url, data=data)
return self._parse_providers(resp.text)
def lookup_drug_prices(self, pricing_url, drug_name, zip_code, sitekey):
"""Look up drug prices with CAPTCHA solving."""
# Load search page
self.session.get(pricing_url)
# Solve CAPTCHA
token = solve_recaptcha(sitekey, pricing_url)
resp = self.session.post(pricing_url, data={
"drug": drug_name,
"zip": zip_code,
"g-recaptcha-response": token,
})
if resp.status_code == 200:
return self._parse_prices(resp.text)
return []
def batch_provider_lookup(self, portal_url, specialties, locations, output_file):
"""Batch search across specialties and locations."""
all_providers = []
for specialty in specialties:
for location in locations:
try:
providers = self.search_providers(
portal_url, specialty, location,
)
for p in providers:
p["specialty_search"] = specialty
p["location_search"] = location
all_providers.extend(providers)
print(f"{specialty} / {location}: {len(providers)} providers")
time.sleep(5)
except Exception as e:
print(f"Error: {specialty} / {location}: {e}")
# Export
if all_providers:
keys = all_providers[0].keys()
with open(output_file, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=keys)
writer.writeheader()
writer.writerows(all_providers)
return all_providers
def _parse_providers(self, html):
soup = BeautifulSoup(html, "html.parser")
providers = []
for card in soup.select(".provider-card, .doctor-result, tr.provider"):
providers.append({
"name": self._text(card, ".name, .provider-name"),
"specialty": self._text(card, ".specialty"),
"address": self._text(card, ".address"),
"phone": self._text(card, ".phone"),
"accepting": self._text(card, ".accepting-patients"),
})
return providers
def _parse_prices(self, html):
soup = BeautifulSoup(html, "html.parser")
prices = []
for row in soup.select(".pharmacy-row, .price-result"):
prices.append({
"pharmacy": self._text(row, ".pharmacy-name"),
"price": self._text(row, ".price, .drug-price"),
"quantity": self._text(row, ".quantity"),
})
return prices
def _text(self, el, selector):
found = el.select_one(selector)
return found.get_text(strip=True) if found else ""
# Usage
collector = HealthcareDataCollector(
proxy="http://user:pass@residential.proxy.com:5000"
)
# Provider search
providers = collector.search_providers(
portal_url="https://provider-directory.example.com/search",
specialty="Cardiology",
location="New York, NY",
)
# Drug pricing
prices = collector.lookup_drug_prices(
pricing_url="https://drug-prices.example.com/compare",
drug_name="atorvastatin",
zip_code="10001",
sitekey="6Lc_xxxxxxx",
)
Für den reCAPTCHA-Fall genügt der sitekey der Seite – CaptchaAI liefert das g-recaptcha-response-Token, das Sie zusammen mit den Suchparametern absenden. Bei Bild-CAPTCHAs laden Sie die Grafik, reichen sie base64-kodiert ein und tragen den erkannten Text ins Formularfeld ein.
Studiendaten aus klinischen Registern erfassen
Register für klinische Studien liefern strukturierte Datensätze – Titel, Status, Sponsor, Studienphase, Teilnehmerzahl und Standort. Die Suchmaske ist typischerweise mit reCAPTCHA v2 abgesichert. Die folgende Funktion baut auf demselben Collector auf: Token lösen, Suchanfrage mit dem Status recruiting absenden, Trefferliste in eine Liste von Dictionaries überführen.
def collect_clinical_trials(search_url, condition, sitekey):
"""Collect clinical trial data for a medical condition."""
collector = HealthcareDataCollector(
proxy="http://user:pass@residential.proxy.com:5000"
)
token = solve_recaptcha(sitekey, search_url)
resp = collector.session.post(search_url, data={
"condition": condition,
"status": "recruiting",
"g-recaptcha-response": token,
})
if resp.status_code != 200:
return []
soup = BeautifulSoup(resp.text, "html.parser")
trials = []
for item in soup.select(".trial-item, .study-result"):
trials.append({
"title": collector._text(item, ".title, h3"),
"status": collector._text(item, ".status"),
"sponsor": collector._text(item, ".sponsor"),
"phase": collector._text(item, ".phase"),
"enrollment": collector._text(item, ".enrollment"),
"location": collector._text(item, ".location"),
})
return trials
Weil beide Beispiele denselben HealthcareDataCollector nutzen, teilen sie sich Session, Proxy-Konfiguration und User-Agent. So bleibt Ihr Zugriffsverhalten über Verzeichnis-, Preis- und Studienabfragen hinweg konsistent.
Datenschutz: öffentliche Daten von personenbezogenen Daten trennen
Die entscheidende Linie verläuft zwischen öffentlich veröffentlichten und personenbezogenen Daten. Anbieterverzeichnisse, regulierte Arzneimittelpreise und Studienregister sind bewusst öffentlich – Patientenakten dagegen niemals. Die folgende Einordnung hilft bei der Priorisierung:
| Datentyp | Sensibilität | Empfehlung |
|---|---|---|
| Anbieterverzeichnisse | Niedrig (öffentliche Angaben) | In der Regel unbedenklich zu erfassen |
| Arzneimittelpreise | Niedrig (öffentliche Preise) | Für Transparenzzwecke zulässig |
| Metadaten klinischer Studien | Niedrig (öffentliche Register) | Für Forschungszwecke geeignet |
| Patientenbewertungen | Mittel | Vor der Auswertung anonymisieren |
| Versicherungstarif-Details | Niedrig (veröffentlichte Tarife) | Für Vergleiche zulässig |
Wichtig: Versuchen Sie niemals, geschützte Gesundheitsinformationen (PHI) zu erfassen. Konzentrieren Sie sich ausschließlich auf öffentlich verfügbare, nicht patientenbezogene Daten – und dokumentieren Sie bei DSGVO-relevanten Läufen Ihre Rechtsgrundlage.
Typische Fehler und ihre Lösung
Die meisten Probleme entstehen nicht am CAPTCHA selbst, sondern an der Reihenfolge und am Tempo der Abfragen.
| Problem | Ursache | Lösung |
|---|---|---|
| Bild-CAPTCHA nicht lesbar | Bild in schlechter Qualität | Erneut anfordern – es wird ein neues Bild erzeugt |
| Anbietersuche liefert leeres Ergebnis | CAPTCHA hat die Suche blockiert | CAPTCHA vor dem Absenden lösen |
| Medikamentenpreis schwankt je nach Region | Geobasierte Preise | Proxy-Standort an die Postleitzahl anpassen |
| Sitzung läuft über mehrere Seiten ab | Portal-Timeout | Suchvorgänge zügig abschließen |
| Rate-Limiting bei Massenabfragen | Zu viele Anfragen | Verzögerungen von 5–10 Sekunden einbauen |
Häufige Fragen
Welche CAPTCHA-Typen kommen auf Gesundheitsportalen am häufigsten vor?
Meist reCAPTCHA v2 und klassische Bild-CAPTCHAs, bei neueren Qualitätsportalen zunehmend Cloudflare Turnstile. CaptchaAI löst alle drei Typen über dieselbe API – Sie brauchen keinen separaten Dienst pro Portal.
Wie schnell löst CaptchaAI ein reCAPTCHA v2 auf einem Portal?
In der Regel in unter 60 Sekunden. Bild-CAPTCHAs sind mit unter 0,5 Sekunden deutlich schneller, Cloudflare Turnstile liegt bei unter 10 Sekunden. Auf den unterstützten Typen erreicht der Dienst eine hohe Erfolgsquote.
Ist das Scraping von Gesundheitsdaten mit der DSGVO vereinbar?
Öffentlich veröffentlichte Daten – Anbieterverzeichnisse, regulierte Arzneimittelpreise, Studienregister – gelten nicht als personenbezogene Gesundheitsdaten. Sobald Sie über Proxys arbeiten, sind IP-Adressen jedoch personenbezogen: prüfen Sie Ihre Rechtsgrundlage und erfassen Sie niemals einzelne Patientendaten.
Wie viele Portale kann ich parallel abfragen?
So viele, wie Ihre Thread-Anzahl zulässt. CaptchaAI rechnet pro gleichzeitigem Thread ab, nicht pro Lösung. Schon der BASIC-Tarif (15 $/Monat, 5 Threads) erlaubt mehrere parallele Abfragen; für größere Crawls skalieren Sie über STANDARD (30 $/Monat, 15 Threads) oder ADVANCE (90 $/Monat, 50 Threads).
Verwandte Leitfäden
- Behördenportale automatisiert abfragen
- Scraping für die akademische Forschung
- Rotierende Residential-Proxys einsetzen
Gesundheitsdaten effizient erfassen – holen Sie sich Ihren CaptchaAI-Schlüssel und automatisieren Sie Anbieter- und Preissuchen.