Das Scraping medizinischer Daten ist eine Aufgabe, die einen besonderen Ansatz bei der Auswahl von Proxys erfordert. Medizinische Portale, Datenbanken klinischer Studien und pharmazeutische Ressourcen verwenden fortschrittliche Schutzsysteme gegen automatisierte Datensammlungen. In diesem Artikel werden wir erörtern, wie man Proxys richtig konfiguriert, um medizinische Informationen sicher zu scrapen, Sperren zu vermeiden und die benötigten Daten effizient zu sammeln.
Warum medizinische Websites Scraping blockieren
Medizinische Portale und Datenbanken sind besonders empfindlich gegenüber automatisierten Informationssammlungen aus mehreren Gründen. Erstens arbeiten viele von ihnen auf kommerzieller Basis und verkaufen den Zugang zu Daten über kostenpflichtige Abonnements. Automatisiertes Scraping kann die Nutzungsbedingungen und Lizenzvereinbarungen verletzen.
Zweitens enthalten medizinische Daten häufig vertrauliche Informationen, die durch Gesetze geschützt sind (HIPAA in den USA, DSGVO in Europa). Die Eigentümer der Ressourcen sind verpflichtet, den Zugang zu solchen Daten zu kontrollieren und deren unbefugte Verbreitung zu verhindern. Daher verwenden sie fortschrittliche Schutzsysteme:
- Rate Limiting — Begrenzung der Anzahl der Anfragen von einer IP-Adresse pro Zeiteinheit (normalerweise 10-50 Anfragen pro Minute)
- Fingerprinting — Analyse der Merkmale des Browsers, der HTTP-Header, der Reihenfolge des Ladens von Ressourcen
- CAPTCHA — Systeme wie reCAPTCHA v3, die bei verdächtiger Aktivität aktiviert werden
- IP-Sperren — vorübergehende oder permanente Sperrung von IP-Adressen von Rechenzentren
- Cloudflare und ähnliche Dienste — Schutz vor Bots auf CDN-Ebene
Der dritte Grund ist die Belastung der Server. Medizinische Datenbanken enthalten oft Millionen von Datensätzen, und massives Scraping kann eine erhebliche Belastung für die Infrastruktur darstellen. Daher kämpfen Administratoren aktiv gegen automatisierte Datensammlungen, indem sie Verhaltensmuster verfolgen, die für Bots charakteristisch sind: gleiche Intervalle zwischen Anfragen, lineares Durchblättern von Seiten, Fehlen von JavaScript und Cookies.
Wichtig: Vor dem Scraping medizinischer Daten sollten Sie unbedingt die Nutzungsbedingungen der Website und die geltenden Gesetze studieren. Einige Daten können urheberrechtlich geschützt sein oder persönliche Informationen von Patienten enthalten. Stellen Sie sicher, dass Ihre Aktivitäten legal sind und keine Rechte Dritter verletzen.
Welchen Proxy-Typ für medizinische Daten wählen
Die Wahl des Proxy-Typs ist entscheidend für das erfolgreiche Scraping medizinischer Daten. Verschiedene Quellen erfordern unterschiedliche Ansätze. Lassen Sie uns die wichtigsten Proxy-Typen und ihre Anwendbarkeit betrachten:
| Proxy-Typ | Vorteile | Nachteile | Wann verwenden |
|---|---|---|---|
| Rechenzentrums-Proxys | Hohe Geschwindigkeit (100+ Mbit/s), niedrige Kosten, stabile Verbindung | Leicht zu erkennen, oft auf geschützten Websites blockiert | Öffentliche Datenbanken ohne strengen Schutz (PubMed, WHO) |
| Residential Proxys | Echte IPs von Heimnutzern, geringes Risiko einer Sperrung, umgehen Cloudflare | Höhere Kosten, variable Geschwindigkeit, können instabil sein | Geschützte kommerzielle Datenbanken (Elsevier, Springer), Websites mit Cloudflare |
| Mobile Proxys | Maximales Vertrauen (IPs von Mobilfunkanbietern), praktisch nicht blockiert | Die teuersten, begrenzte Geografie, können langsamer sein | Besonders geschützte Ressourcen, wenn Residential Proxys nicht helfen |
| ISP Proxys | Rechenzentrums-Geschwindigkeit + Vertrauen von Residential Proxys, statische IPs | Durchschnittliche Kosten, begrenzte Verfügbarkeit | Langfristiges Scraping von einer IP, wenn Stabilität erforderlich ist |
Für die meisten Scraping-Aufgaben medizinischer Daten wird empfohlen, Residential Proxys zu verwenden. Sie bieten das optimale Gleichgewicht zwischen Kosten und Effizienz. Rechenzentrums-Proxys eignen sich nur für offene Quellen ohne Schutz. Mobile Proxys sollten nur in extremen Fällen verwendet werden, wenn andere Typen nicht funktionieren.
Empfehlungen zur Auswahl für spezifische Quellen
- PubMed, PubMed Central — Rechenzentrums-Proxys sind ausreichend, aber mit einer Geschwindigkeitsbegrenzung von 3 Anfragen pro Sekunde
- ClinicalTrials.gov — Rechenzentrums-Proxys, es gibt eine offizielle API
- Elsevier, Springer, Wiley — Residential Proxys sind erforderlich, verwenden fortschrittliches Fingerprinting
- DrugBank, RxList — Residential Proxys, aktive Schutzmaßnahmen gegen Scraping
- FDA, EMA-Datenbanken — Rechenzentrums-Proxys sind geeignet, aber mit langsamer Scraping-Geschwindigkeit
Hauptquellen medizinischer Daten und deren Schutz
Medizinische Daten sind über viele Quellen verteilt, von denen jede ihre eigenen Besonderheiten und Schutzstufen hat. Das Verständnis dieser Besonderheiten hilft, die Scraping-Strategie richtig einzustellen.
Öffentliche staatliche Datenbanken
PubMed/PubMed Central — die größte Datenbank medizinischer Publikationen, enthält über 35 Millionen Datensätze. Die National Library of Medicine (NLM) der USA bietet eine offizielle API E-utilities, die der bevorzugte Zugang zu den Daten ist. Direktes Scraping der Weboberfläche ist möglich, aber auf 3 Anfragen pro Sekunde von einer IP-Adresse begrenzt. Eine Überschreitung des Limits führt zu einer vorübergehenden Sperrung von 24 Stunden.
ClinicalTrials.gov — eine Datenbank klinischer Studien, enthält Informationen zu über 400.000 Studien in 220 Ländern. Bietet auch eine API für den programmgesteuerten Zugriff. Die Weboberfläche ist durch Rate Limiting geschützt — maximal 100 Anfragen in 5 Minuten von einer IP-Adresse. Es wird ein grundlegender Schutz gegen Bots verwendet, aber ohne Cloudflare.
FDA Drugs Database — eine Datenbank genehmigter Arzneimittel der FDA. Offener Zugang über die Weboberfläche und die API openFDA. Einschränkungen: 240 Anfragen pro Minute für anonyme Benutzer, 1000 Anfragen pro Minute mit API-Schlüssel. Sperrungen sind selten, aber bei aggressivem Scraping möglich.
Kommerzielle wissenschaftliche Verlage
Elsevier (ScienceDirect) — einer der größten Verlage wissenschaftlicher Literatur. Verwendet mehrstufigen Schutz: Cloudflare, Fingerprinting des Browsers, Analyse des Nutzerverhaltens. Erkennt Muster automatisierter Downloads: sequenzieller Zugriff auf Artikel, Fehlen von JavaScript, untypische User-Agent. Bei Entdeckung des Scraping werden IPs auf Kontoebene blockiert und die gesamte Institution kann gesperrt werden. Die Verwendung von Residential Proxys mit Rotation und vollständiger Browseremulation ist unbedingt erforderlich.
Springer Nature — ähnliche Schutzmaßnahmen, zusätzlich wird die Scrollgeschwindigkeit der Seiten und die Mausbewegungen überwacht. Verwendet Machine Learning zur Erkennung von Bots. Es wird empfohlen, nicht mehr als 10-15 Artikel pro Stunde von einer IP-Adresse zu scrapen, mit randomisierten Verzögerungen zwischen den Anfragen.
Wiley Online Library — weniger aggressiver Schutz, erfordert jedoch dennoch die Verwendung von Proxys. Erlaubt etwa 50 Anfragen pro Stunde von einer IP-Adresse ohne Sperrung. Verwendet Session-Cookies zur Verfolgung der Aktivität.
Pharmazeutische Datenbanken
DrugBank — umfassende Datenbank von Arzneimitteln. Die kostenlose Version ist auf die Weboberfläche beschränkt, die kommerzielle Version bietet API und Datenexporte. Die Webversion ist durch Cloudflare und Rate Limiting geschützt — maximal 20 Anfragen pro Minute. Erkennt Automatisierung durch das Fehlen von Cookies und JavaScript.
RxList, Drugs.com — beliebte Arzneimittelverzeichnisse für Verbraucher. Verwenden Cloudflare und kämpfen aktiv gegen Scraping. Blockieren IPs von Rechenzentren praktisch sofort. Es werden Residential Proxys und eine langsame Scraping-Geschwindigkeit (5-10 Seiten pro Minute) benötigt.
IP-Rotation für langfristiges Scraping einrichten
Die richtige Rotation von IP-Adressen ist ein Schlüsselfaktor für erfolgreiches Scraping medizinischer Daten. Es gibt zwei Hauptansätze: Rotation auf Anfrageebene und zeitbasierte Rotation.
Rotation auf Anfrageebene
Bei diesem Ansatz wird jede Anfrage über eine neue IP-Adresse gesendet. Dies minimiert das Risiko einer Sperrung, kann jedoch Probleme mit Websites verursachen, die Sitzungen über Cookies verfolgen. Geeignet für das Scraping von Listen und Katalogen, bei denen kein Sitzungsstatus aufrechterhalten werden muss.
Die meisten Anbieter von Residential Proxys bieten eine automatische Rotation über einen speziellen Endpunkt an. Zum Beispiel, wenn Sie einen rotating proxy endpoint verwenden, erhält jede neue TCP-Verbindung eine neue IP. Dies funktioniert automatisch mit Bibliotheken wie requests in Python, da standardmäßig für jede Anfrage eine neue Verbindung hergestellt wird.
Zeitbasierte Rotation (Sticky Sessions)
Sticky Sessions ermöglichen die Verwendung einer IP-Adresse für einen bestimmten Zeitraum (normalerweise 5-30 Minuten), nach dem eine automatische Änderung erfolgt. Dies ist nützlich für Websites, die eine Authentifizierung erfordern oder den Sitzungsstatus über Cookies verfolgen. Sie können mehrere Seiten von einer IP-Adresse scrapen und dabei das Verhalten eines echten Benutzers imitieren, bevor die IP automatisch gewechselt wird.
Für medizinische Websites wird empfohlen, Sticky Sessions mit einer Dauer von 10-15 Minuten zu verwenden. In dieser Zeit können 10-20 Seiten gescraped werden (je nach Verzögerungen), danach wird die IP gewechselt und Sie beginnen eine "neue Sitzung". Dies sieht natürlich aus und verringert das Risiko einer Erkennung.
Größe des IP-Pools
Für langfristiges Scraping ist die Größe des Pools verfügbarer IP-Adressen wichtig. Wenn Sie dieselbe Gruppe von 100 IPs über eine Woche hinweg verwenden, kann die Website ein Muster bemerken und alle diese Adressen blockieren. Residential Proxys bieten normalerweise Zugang zu Millionen von IPs, was die Wiederverwendung derselben Adresse praktisch ausschließt.
Bei der Verwendung von Rechenzentrums-Proxys wird empfohlen, einen Pool von mindestens 500-1000 IPs für das Scraping eines mittleren Volumens (10.000-50.000 Seiten pro Monat) zu haben. Für großangelegtes Scraping (Hunderte von Tausenden von Seiten) ist es besser, Residential Proxys mit ihren riesigen IP-Pools zu verwenden.
Rotationstipps für verschiedene Quellen:
- PubMed — Rotation ist nicht erforderlich, 1 IP mit Einhaltung des Rate Limits reicht aus
- Kommerzielle Verlage — Sticky Sessions von 10-15 Minuten, neue IP alle 15-20 Seiten
- Pharmazeutische Datenbanken — Rotation bei jeder Anfrage oder Sticky Sessions von 5 Minuten
- Websites mit Cloudflare — Sticky Sessions sind erforderlich, Rotation auf Anfrageebene funktioniert nicht
Python-Codebeispiele für das Scraping mit Proxys
Lassen Sie uns praktische Beispiele für die Konfiguration von Proxys für das Scraping medizinischer Daten unter Verwendung beliebter Python-Bibliotheken betrachten. Wir beginnen mit einem grundlegenden Beispiel und werden es schrittweise komplizierter gestalten.
Grundkonfiguration mit der Bibliothek requests
import requests
from time import sleep
import random
# Proxy-Konfiguration (ersetzen Sie durch Ihre Daten)
PROXY_HOST = "proxy.example.com"
PROXY_PORT = "8080"
PROXY_USER = "username"
PROXY_PASS = "password"
proxies = {
'http': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
'https': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}'
}
# Header zur Imitation eines echten Browsers
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'DNT': '1',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'
}
# Beispielanfrage an PubMed
url = "https://pubmed.ncbi.nlm.nih.gov/?term=diabetes"
try:
response = requests.get(url, proxies=proxies, headers=headers, timeout=30)
print(f"Statuscode: {response.status_code}")
print(f"Inhaltslänge: {len(response.content)}")
# Verzögerung zwischen Anfragen hinzufügen (unbedingt für PubMed)
sleep(random.uniform(1.0, 3.0))
except requests.exceptions.RequestException as e:
print(f"Fehler: {e}")
Fortgeschrittene Konfiguration mit Rotation und Retry-Logik
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from time import sleep
import random
class ProxyRotator:
def __init__(self, proxy_list):
"""
proxy_list: Liste von Dictionaries mit Proxys
[{'http': 'http://user:pass@host:port', 'https': '...'}, ...]
"""
self.proxy_list = proxy_list
self.current_index = 0
def get_next_proxy(self):
"""Nächsten Proxy aus der Liste abrufen"""
proxy = self.proxy_list[self.current_index]
self.current_index = (self.current_index + 1) % len(self.proxy_list)
return proxy
def create_session_with_retries():
"""Eine Sitzung mit automatischen Wiederholungen bei Fehlern erstellen"""
session = requests.Session()
# Automatische Wiederholungen einrichten
retry_strategy = Retry(
total=3, # maximal 3 Versuche
backoff_factor=1, # Verzögerung zwischen den Versuchen: 1, 2, 4 Sekunden
status_forcelist=[429, 500, 502, 503, 504], # Codes für Wiederholungen
allowed_methods=["GET", "POST"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)
return session
def scrape_with_rotation(urls, proxy_rotator):
"""Scraping einer Liste von URLs mit Proxy-Rotation"""
session = create_session_with_retries()
results = []
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
}
for url in urls:
# Für jede Anfrage neuen Proxy abrufen
proxy = proxy_rotator.get_next_proxy()
try:
response = session.get(
url,
proxies=proxy,
headers=headers,
timeout=30
)
if response.status_code == 200:
results.append({
'url': url,
'status': 'success',
'content_length': len(response.content)
})
print(f"✓ Erfolg: {url}")
else:
results.append({
'url': url,
'status': 'failed',
'error': f"Statuscode: {response.status_code}"
})
print(f"✗ Fehler: {url} (Status: {response.status_code})")
except requests.exceptions.RequestException as e:
results.append({
'url': url,
'status': 'error',
'error': str(e)
})
print(f"✗ Fehler: {url} ({e})")
# Zufällige Verzögerung zwischen Anfragen (wichtig!)
sleep(random.uniform(2.0, 5.0))
return results
# Beispielverwendung
proxy_list = [
{
'http': 'http://user1:pass1@proxy1.example.com:8080',
'https': 'http://user1:pass1@proxy1.example.com:8080'
},
{
'http': 'http://user2:pass2@proxy2.example.com:8080',
'https': 'http://user2:pass2@proxy2.example.com:8080'
}
]
rotator = ProxyRotator(proxy_list)
urls_to_scrape = [
"https://pubmed.ncbi.nlm.nih.gov/?term=diabetes",
"https://pubmed.ncbi.nlm.nih.gov/?term=cancer",
"https://pubmed.ncbi.nlm.nih.gov/?term=covid"
]
results = scrape_with_rotation(urls_to_scrape, rotator)
Verwendung von Selenium für Websites mit JavaScript
Viele moderne medizinische Websites verwenden JavaScript zum Laden von Inhalten. In solchen Fällen ist ein Headless-Browser erforderlich:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
def create_proxy_driver(proxy_host, proxy_port, proxy_user, proxy_pass):
"""Erstellen Sie den Chrome WebDriver mit Proxy"""
chrome_options = Options()
# Headless-Modus (ohne GUI)
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
# Proxy-Konfiguration
chrome_options.add_argument(f'--proxy-server=http://{proxy_host}:{proxy_port}')
# Automatisierung deaktivieren (wichtig zur Umgehung der Erkennung)
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
# User-Agent
chrome_options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')
driver = webdriver.Chrome(options=chrome_options)
# Für Proxys mit Authentifizierung müssen Sie eine Erweiterung verwenden
# oder über capabilities konfigurieren (komplizierterer Ansatz)
return driver
def scrape_with_selenium(url, driver):
"""Scraping einer Seite mit Warten auf das Laden von JavaScript"""
driver.get(url)
# Warten auf das Laden des Elements (z.B. Suchergebnisse)
try:
wait = WebDriverWait(driver, 10)
results = wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "results-article"))
)
# Daten extrahieren
articles = driver.find_elements(By.CLASS_NAME, "results-article")
data = []
for article in articles:
try:
title = article.find_element(By.CLASS_NAME, "docsum-title").text
authors = article.find_element(By.CLASS_NAME, "docsum-authors").text
data.append({
'title': title,
'authors': authors
})
except:
continue
return data
except Exception as e:
print(f"Fehler beim Warten auf Elemente: {e}")
return []
# Beispielverwendung
proxy_host = "proxy.example.com"
proxy_port = "8080"
proxy_user = "username"
proxy_pass = "password"
driver = create_proxy_driver(proxy_host, proxy_port, proxy_user, proxy_pass)
try:
url = "https://pubmed.ncbi.nlm.nih.gov/?term=diabetes"
results = scrape_with_selenium(url, driver)
for result in results:
print(f"Titel: {result['title']}")
print(f"Autoren: {result['authors']}\n")
finally:
driver.quit()
Kontrolle der Anfragespeed und Umgehung von Rate Limiting
Rate Limiting ist eines der Hauptschutzmittel medizinischer Websites gegen Scraping. Die richtige Einstellung der Anfragespeed ist entscheidend für langfristiges Scraping ohne Sperrungen.
Bestimmung einer sicheren Geschwindigkeit
Der erste Schritt besteht darin, die Limits der jeweiligen Website zu bestimmen. Dies kann experimentell erfolgen, indem die Anfragespeed schrittweise erhöht wird, bis Fehler 429 (Too Many Requests) oder Sperrungen auftreten. Für die meisten medizinischen Websites sind sichere Werte:
- PubMed — maximal 3 Anfragen pro Sekunde (offizielle Empfehlung)
- ClinicalTrials.gov — 20 Anfragen pro Minute sind sicher, bis zu 100 in 5 Minuten sind zulässig
- Kommerzielle Verlage — 10-15 Anfragen pro Stunde von einer IP
- Pharmazeutische Datenbanken — 5-10 Anfragen pro Minute
Implementierung eines Rate Limiters in Python
import time
from collections import deque
class RateLimiter:
def __init__(self, max_calls, period):
"""
max_calls: maximales Anzahl an Aufrufen
period: Zeitraum in Sekunden
Zum Beispiel: RateLimiter(3, 1) = 3 Anfragen pro Sekunde
"""
self.max_calls = max_calls
self.period = period
self.calls = deque()
def __call__(self, func):
"""Dekorator zur Begrenzung der Geschwindigkeit der Funktionsaufrufe"""
def wrapper(*args, **kwargs):
now = time.time()
# Alte Aufrufe außerhalb des Zeitraums entfernen
while self.calls and self.calls[0] < now - self.period:
self.calls.popleft()
# Wenn das Limit erreicht ist, warten
if len(self.calls) >= self.max_calls:
sleep_time = self.period - (now - self.calls[0])
if sleep_time > 0:
print(f"Rate Limit erreicht, warte {sleep_time:.2f}s")
time.sleep(sleep_time)
# Nach dem Warten leeren
self.calls.clear()
# Zeit des Aufrufs aufzeichnen
self.calls.append(time.time())
# Funktion ausführen
return func(*args, **kwargs)
return wrapper
# Beispielverwendung
@RateLimiter(max_calls=3, period=1) # 3 Anfragen pro Sekunde
def fetch_pubmed_page(url):
response = requests.get(url, headers=headers, proxies=proxies)
return response
# Jetzt hält die Funktion automatisch das Rate Limit ein
for i in range(10):
result = fetch_pubmed_page(f"https://pubmed.ncbi.nlm.nih.gov/?term=test&page={i}")
print(f"Seite {i} abgerufen")
Adaptives Rate Limiting
Ein fortgeschrittenerer Ansatz ist die adaptive Anpassung der Geschwindigkeit basierend auf den Antworten des Servers. Wenn wir Fehler 429 oder 503 erhalten, reduzieren wir automatisch die Geschwindigkeit:
import time
import random
class AdaptiveRateLimiter:
def __init__(self, initial_delay=1.0, max_delay=60.0):
self.current_delay = initial_delay
self.initial_delay = initial_delay
self.max_delay = max_delay
self.success_count = 0
def wait(self):
"""Warten vor der nächsten Anfrage"""
# Fügen Sie Zufälligkeit für Natürlichkeit hinzu
actual_delay = self.current_delay * random.uniform(0.8, 1.2)
time.sleep(actual_delay)
def on_success(self):
"""Wird bei erfolgreicher Anfrage aufgerufen"""
self.success_count += 1
# Nach 10 erfolgreichen Anfragen etwas schneller werden
if self.success_count >= 10:
self.current_delay = max(
self.initial_delay,
self.current_delay * 0.9
)
self.success_count = 0
def on_rate_limit(self):
"""Wird bei Erhalt von 429 oder ähnlichen Fehlern aufgerufen"""
# Verdoppeln Sie die Verzögerung, aber nicht mehr als das Maximum
self.current_delay = min(
self.current_delay * 2,
self.max_delay
)
self.success_count = 0
print(f"Rate Limit erreicht! Verzögerung auf {self.current_delay:.2f}s erhöhen")
def on_error(self):
"""Wird bei anderen Fehlern aufgerufen"""
# Verzögerung etwas erhöhen
self.current_delay = min(
self.current_delay * 1.5,
self.max_delay
)
self.success_count = 0
# Beispielverwendung
limiter = AdaptiveRateLimiter(initial_delay=2.0, max_delay=30.0)
for url in urls_to_scrape:
limiter.wait()
try:
response = requests.get(url, proxies=proxies, headers=headers)
if response.status_code == 200:
limiter.on_success()
# Datenverarbeitung
elif response.status_code == 429:
limiter.on_rate_limit()
# Später wiederholen
else:
limiter.on_error()
except requests.exceptions.RequestException:
limiter.on_error()
Die richtigen Header und User-Agent für medizinische Websites
Medizinische Websites analysieren die HTTP-Header zur Erkennung von Bots. Falsche oder fehlende Header sind häufige Ursachen für Sperrungen, selbst bei der Verwendung hochwertiger Proxys.
Obligatorische Header
Das minimale Set an Headern, das in jeder Anfrage vorhanden sein sollte:
headers = {
# User-Agent — unbedingt einen aktuellen Browser
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
# Accept — die von dem Browser akzeptierten Inhaltstypen
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
# Accept-Language — die Sprache des Benutzers
'Accept-Language': 'en-US,en;q=0.9',
# Accept-Encoding — Unterstützung für Kompression
'Accept-Encoding': 'gzip, deflate, br',
# Connection — Verbindung aufrechterhalten
'Connection': 'keep-alive',
# Upgrade-Insecure-Requests — automatischer Wechsel zu HTTPS
'Upgrade-Insecure-Requests': '1',
# DNT — Do Not Track (optional, aber erhöht die Realitätsnähe)
'DNT': '1',
# Sec-Fetch-* Header (wichtig für moderne Browser)
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-User': '?1',
# Cache-Control
'Cache-Control': 'max-age=0'
}
Rotation des User-Agent
Die Verwendung desselben User-Agent kann verdächtig sein. Es wird empfohlen, zwischen mehreren aktuellen Browsern zu rotieren:
import random
USER_AGENTS = [
# Chrome unter Windows
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
# Chrome unter Mac
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
# Firefox unter Windows
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
# Firefox unter Mac
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0',
# Safari unter Mac
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15',
# Edge unter Windows
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0'
]
def get_random_headers():
"""Erhalten Sie Header mit zufälligem User-Agent"""
return {
'User-Agent': random.choice(USER_AGENTS),
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'DNT': '1'
}
# Verwendung
for url in urls:
headers = get_random_headers()
response = requests.get(url, headers=headers, proxies=proxies)
Referer und Origin für Formulare
Bei der Arbeit mit Suchformularen oder beim Senden von POST-Anfragen sollten Sie unbedingt die Header Referer und Origin hinzufügen:
# Für POST-Anfragen an das Suchformular
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': 'https://example.com',
'Referer': 'https://example.com/search',
'Connection': 'keep-alive'
}
# POST-Anfrage mit Formulardaten
data = {
'query': 'diabetes',
'page': '1'
}
response = requests.post(
'https://example.com/search',
headers=headers,
data=data,
proxies=proxies
)
Typische Probleme und deren Lösungen
Beim Scraping medizinischer Daten treten spezifische Probleme auf. Lassen Sie uns die häufigsten betrachten und wie man sie löst.
Problem: Cloudflare blockiert alle Anfragen
Symptome: Sie erhalten eine Seite mit dem Text "Überprüfung Ihres Browsers" oder einen Fehler 403 Forbidden mit Erwähnung von Cloudflare.
Lösung:
- Verwenden Sie Residential Proxys anstelle von Rechenzentrums-Proxys — Cloudflare blockiert standardmäßig IPs von Rechenzentren
- Wechseln Sie zu Selenium oder Puppeteer — Headless-Browser durchlaufen Cloudflare-Überprüfungen besser
- Verwenden Sie die Bibliothek cloudscraper für Python — sie umgeht automatisch den grundlegenden Schutz von Cloudflare
- Aktivieren Sie Cookies und JavaScript — Cloudflare überprüft deren Vorhandensein
- Fügen Sie TLS-Fingerprinting hinzu — verwenden Sie curl_cffi, um einen echten Browser auf TLS-Ebene zu imitieren
Problem: Ich erhalte den Fehler 429 Too Many Requests
Symptome: Nach mehreren erfolgreichen Anfragen beginnt der Server, 429 zurückzugeben.
Lösung:
- Erhöhen Sie die Verzögerung zwischen den Anfragen — versuchen Sie, mit 3-5 Sekunden zu beginnen
- Aktivieren Sie die IP-Rotation — jede Anfrage über eine neue IP hebt das Rate Limiting auf
- Überprüfen Sie den Header Retry-After in der Antwort 429 — er gibt an, wie viele Sekunden gewartet werden muss
- Verwenden Sie exponentielle Verzögerung bei Wiederholungen — 1s, 2s, 4s, 8s usw.
Problem: Proxys arbeiten langsam oder fallen häufig aus
Symptome: Timeout-Fehler, sehr lange Ladezeiten, Verbindungsabbrüche.
Lösung:
- Erhöhen Sie den Timeout in den Anfragen auf 30-60 Sekunden — Residential Proxys können langsamer sein
- Verwenden Sie geografisch nahe Proxys — wenn Sie eine europäische Website scrapen, verwenden Sie europäische IPs
- Überprüfen Sie die Qualität des Proxy-Anbieters — billige Proxys sind oft instabil
- Fügen Sie eine Retry-Logik hinzu — wiederholen Sie die Anfrage automatisch bei Verbindungsfehlern
- Verwenden Sie Connection Pooling — wiederverwenden Sie TCP-Verbindungen über requests.Session()
Problem: Die Website erfordert Authentifizierung oder ein Abonnement
Symptome: Der Zugang zu den Volltexten der Artikel ist eingeschränkt, eine Anmeldung ist erforderlich.
Lösung:
- Verwenden Sie institutionellen Zugang — viele Universitäten und Krankenhäuser haben Abonnements
- Überprüfen Sie, ob Open Access-Versionen vorhanden sind — viele Artikel sind kostenlos über Repositories verfügbar
- Verwenden Sie APIs anstelle von Scraping — einige Verlage bieten APIs für Forscher an
- Scrapen Sie nur Metadaten (Titel, Autoren, Abstracts) — diese sind normalerweise kostenlos verfügbar
Problem: JavaScript-Inhalte werden nicht geladen
Symptome: Im HTML sind die benötigten Daten nicht vorhanden, es sind nur Lade-Spinners oder leere Container sichtbar.
Lösung:
- Wechseln Sie zu Selenium/Puppeteer — sie führen JavaScript aus
- Finden Sie den API-Endpunkt — öffnen Sie die DevTools im Browser, Tab Netzwerk, und suchen Sie nach XHR-Anfragen mit Daten
- Verwenden Sie requests-html — eine Bibliothek mit...