User-Agent-Rotation beim Scraping – so hab ich’s gelöst
Ausgangspunkt
Bei mehreren Requests auf dieselbe Domain kam es regelmäßig zu Captchas oder 403-Fehlern. Ursache: mein Script sendete bei jedem Request denselben User-Agent – das sieht nach Bot aus. Ziel war, die Header realistischer zu gestalten – vor allem User-Agent rotieren.
⚙️ Ansatz & Setup
Ich wollte keine riesige Browseremulation, sondern einfach in meinem Python-HTTP-Client (httpx) zufällig rotierende User-Agents einbauen.
Ich habe ein Set gängiger Desktop- und Mobile-Strings genommen, gemischt nach realer Verteilung.
Beispielhafte Liste
user_agents = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
"Mozilla/5.0 (Linux; Android 11; SM-G991B)...",
"Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X)...",
...
]
Python: User-Agent bei jedem Request wechseln
import httpx
import random
url = "https://zielseite.de/"
headers = {
"User-Agent": random.choice(user_agents),
"Accept": "text/html,application/xhtml+xml",
"Accept-Language": "de-DE,de;q=0.9",
}
response = httpx.get(url, headers=headers)
print(response.status_code)
Wichtige Erkenntnisse
- Nur User-Agent rotieren bringt wenig – wichtig ist der ganze Header-Block
- Mobile-User-Agents wirken oft glaubwürdiger (viele Sites mobil zuerst)
- Immer mit
Accept-Language,Accept, evtl.Refererkombinieren
Optional: Ganze Header-Presets rotieren
header_presets = [
{
"User-Agent": "...Windows...",
"Accept": "text/html,application/xhtml+xml",
"Accept-Language": "de-DE,de;q=0.9"
},
{
"User-Agent": "...iPhone...",
"Accept": "text/html,application/xhtml+xml",
"Accept-Language": "de-DE,de;q=0.9"
},
...
]
headers = random.choice(header_presets)
Bonus: Was ich vermeiden würde
- Fiktive oder falsch formatierte User-Agents (z. B. von alten Generatoren)
- Gleichzeitiges Rotieren von Proxy + User-Agent ohne Grund
- User-Agent ohne andere passende Header – fällt auf
Fazit
User-Agent-Rotation ist kein Wundermittel – aber ein sinnvoller Baustein gegen triviale Blockaden. Wichtig ist nicht nur der String selbst, sondern dass das ganze Header-Set zusammenpasst.
Stand: 04/2025 – funktioniert zuverlässig bei typischen Scraping-Zielen.