Ein Ticket-Monitor beantwortet eine einzige Frage im Minutentakt: Hat sich die Verfügbarkeit für ein Event geändert? Damit dieser Check zuverlässig läuft, muss er reCAPTCHA v2, Cloudflare Turnstile und Cloudflare-Challenge-Seiten passieren, die praktisch jede Ticketplattform zwischen Ihren Request und die eigentliche Seite schiebt. Genau an dieser Stelle setzt CaptchaAI an: Der Dienst löst die CAPTCHA-Abfrage, der Token wandert zurück in Ihre Anfrage, und Ihr Monitor liest den Verfügbarkeitsstatus aus – ohne dass Sie an jeder Abfrage manuell hängen bleiben.
Dieser Leitfaden baut einen kompletten Überwachungs-Workflow in Python auf: einen wiederverwendbaren CAPTCHA-Helfer, eine Monitor-Klasse mit Änderungserkennung und Alerts sowie einen Cron-Job für die regelmäßige Ausführung. Alle Preise verstehen sich in US-Dollar.
Fairer Einsatz: Wo Ticket-Monitoring zulässig ist
Automatisiertes Monitoring ist ein Werkzeug – der Kontext entscheidet über die Zulässigkeit. Prüfen Sie vor dem ersten Lauf die AGB und die robots.txt der jeweiligen Plattform und beschränken Sie sich auf Seiten, deren Überwachung Ihnen erlaubt ist oder die Sie selbst betreiben (etwa eine eigene Staging-Umgebung für QA-Zwecke). Der hier gezeigte Workflow liest ausschließlich einen Verfügbarkeitsstatus aus und löst keine Käufe aus.
Für Leser im DACH-Raum kommt ein datenschutzrechtlicher Punkt hinzu: Sobald Sie mit rotierenden Proxys arbeiten, verarbeiten Sie IP-Adressen, die nach DSGVO als personenbezogene Daten gelten können. Klären Sie die Rechtsgrundlage für Ihre Datenflüsse und dokumentieren Sie, wozu Sie welche Seiten abfragen. Konservative, gut belegte Nutzung baut hier mehr Vertrauen auf als aggressive Prüffrequenzen.
Der Überwachungs-Workflow im Überblick
Der Ablauf ist eine schlanke Schleife: Events konfigurieren, Verfügbarkeit prüfen, bei einer CAPTCHA-Abfrage lösen und den Request wiederholen, dann den Status parsen und – nur bei einer echten Änderung – einen Alert senden.
Configure events → Check availability → CAPTCHA?
↓ Yes
Solve via CaptchaAI → Retry
↓ No
Parse availability → Changed?
↓ Yes
Send alert
Der entscheidende Teil ist die Änderungserkennung: Der Monitor speichert den letzten bekannten Status je Event und meldet nur, wenn sich „ausverkauft" zu „verfügbar" (oder umgekehrt) dreht. So bleibt das Log ruhig und Sie werden nicht bei jedem Durchlauf benachrichtigt.
Voraussetzungen für den Ticket-Monitor
Drei Bausteine reichen für den Start:
| Anforderung | Einzelheiten |
|---|---|
| CaptchaAI API-Schlüssel | captchaai.com |
| Python 3.8+ | Mit requests |
| Proxy | Residential-Proxy empfohlen |
Ein Residential-Proxy ist keine Kür, sondern Pflicht: Ticketseiten blockieren Rechenzentrums-IPs aggressiv, und jeder Block erzeugt zusätzliche CAPTCHA-Abfragen. Für den Betrieb des Monitors selbst genügt ein günstiger VPS bei Anbietern wie Hetzner oder netcup – der eigentliche Rechenaufwand liegt beim Solver, nicht bei Ihnen.
pip install requests
CAPTCHA-Lösung als wiederverwendbarer Helfer
Die Funktion solve_captcha kapselt den kompletten CaptchaAI-Ablauf: Aufgabe an in.php übermitteln, kurz warten und dann das Ergebnis an res.php abfragen (Polling). Der Parameter method steuert den Typ – userrecaptcha für reCAPTCHA v2, turnstile für Cloudflare Turnstile. Das anfängliche Warteintervall ist bewusst typabhängig, weil Turnstile im Schnitt deutlich schneller fertig ist als reCAPTCHA.
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_captcha(method, params):
"""Generic CaptchaAI solver for any supported method."""
params["key"] = API_KEY
params["json"] = 1
submit = requests.post("https://ocr.captchaai.com/in.php", data=params).json()
if submit.get("status") != 1:
raise RuntimeError(f"Submit error: {submit.get('request')}")
task_id = submit["request"]
initial_wait = 10 if method == "turnstile" else 20
time.sleep(initial_wait)
for _ in range(30):
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
return result["request"]
if result.get("request") != "CAPCHA_NOT_READY":
raise RuntimeError(f"Solve error: {result['request']}")
time.sleep(5)
raise TimeoutError("Solve timed out")
Der zurückgegebene Token ist nur kurz gültig – Tokens laufen typischerweise nach rund 120 Sekunden ab. Lösen Sie also erst dann, wenn Sie den Token unmittelbar danach absenden, und legen Sie ihn nicht auf Vorrat.
Der Ticket-Monitor: Verfügbarkeit prüfen und Alerts senden
Die Klasse TicketMonitor verwaltet eine Session mit festem User-Agent und optionalem Proxy. In check_event erkennt sie anhand des HTML, ob eine reCAPTCHA- oder Turnstile-Abfrage vorliegt, holt den passenden Sitekey, lässt ihn lösen und wiederholt den Request mit dem Token im richtigen Feld (g-recaptcha-response bzw. cf-turnstile-response). Danach parst _parse_availability den Status, und _send_alert meldet nur echte Änderungen.
from datetime import datetime
import json
class TicketMonitor:
def __init__(self, proxy=None):
self.session = requests.Session()
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
})
if proxy:
self.session.proxies = {
"http": f"http://{proxy}",
"https": f"http://{proxy}"
}
self.last_status = {}
def check_event(self, event):
"""Check ticket availability for an event, solving CAPTCHAs if needed."""
url = event["url"]
response = self.session.get(url)
# Handle CAPTCHA if detected
if "g-recaptcha" in response.text or "recaptcha" in response.text:
sitekey = self._extract_sitekey(response.text)
if sitekey:
token = solve_captcha("userrecaptcha", {
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": url
})
response = self.session.post(url, data={
"g-recaptcha-response": token
})
elif "cf-turnstile" in response.text:
sitekey = self._extract_turnstile_key(response.text)
if sitekey:
token = solve_captcha("turnstile", {
"method": "turnstile",
"sitekey": sitekey,
"pageurl": url
})
response = self.session.post(url, data={
"cf-turnstile-response": token
})
# Parse availability
availability = self._parse_availability(response.text, event)
# Check for changes
event_key = event["name"]
if event_key in self.last_status:
if availability != self.last_status[event_key]:
self._send_alert(event, availability)
self.last_status[event_key] = availability
return availability
def _extract_sitekey(self, html):
if 'data-sitekey="' in html:
start = html.index('data-sitekey="') + 14
end = html.index('"', start)
return html[start:end]
return None
def _extract_turnstile_key(self, html):
if 'data-sitekey="' in html:
start = html.index('data-sitekey="') + 14
end = html.index('"', start)
return html[start:end]
return None
def _parse_availability(self, html, event):
"""Parse ticket availability. Customize per ticketing site."""
available = "sold out" not in html.lower()
return {
"event": event["name"],
"available": available,
"checked_at": datetime.now().isoformat()
}
def _send_alert(self, event, availability):
"""Send availability change notification."""
status = "AVAILABLE" if availability["available"] else "SOLD OUT"
print(f"[ALERT] {event['name']}: {status}")
def monitor_all(self, events):
"""Check all events and return results."""
results = []
for event in events:
try:
result = self.check_event(event)
results.append(result)
print(f"[OK] {event['name']}: {'available' if result['available'] else 'sold out'}")
except Exception as e:
print(f"[ERROR] {event['name']}: {e}")
return results
# Usage
events = [
{
"name": "Concert - Madison Square Garden - Aug 15",
"url": "https://example-tickets.com/event/12345"
},
{
"name": "Basketball Finals - Game 7",
"url": "https://example-tickets.com/event/67890"
}
]
monitor = TicketMonitor(proxy="user:pass@proxy.example.com:8080")
results = monitor.monitor_all(events)
for r in results:
print(json.dumps(r, indent=2))
Die Methode _parse_availability ist bewusst simpel gehalten (Suche nach „sold out"). In der Praxis passen Sie diese Logik an die HTML-Struktur der jeweiligen Seite an – ein CSS-Selektor auf den Buchen-Button oder eine Statuszeile ist meist robuster als eine reine Textsuche.
Erwartete Ausgabe:
[OK] Concert - Madison Square Garden - Aug 15: available
[OK] Basketball Finals - Game 7: sold out
Prüfungen automatisch planen
Ein Monitor lebt vom Takt. Ein Cron-Job führt das Skript in festen Abständen aus und schreibt die Ausgabe in ein Log:
# Check every 15 minutes
*/15 * * * * cd /path/to/project && python ticket_monitor.py >> /var/log/tickets.log 2>&1
Fünfzehn Minuten sind ein guter Kompromiss zwischen Aktualität und Last. Wer enger prüft, provoziert mehr CAPTCHA-Abfragen und riskiert schneller einen Block – ein Zielkonflikt, den kein Solver auflöst.
Typische Probleme beim Ticket-Monitoring
| Problem | Ursache | Lösung |
|---|---|---|
| Häufige CAPTCHAs bei jedem Check | Gleiche IP, keine Sitzungspersistenz | Cookies verwenden und Residential-Proxys rotieren |
| Nach wenigen Prüfungen gesperrt | Rate-Limiting | Prüfintervalle erhöhen, Proxy-Rotation nutzen |
| Falscher Verfügbarkeitsstatus | Seitenstruktur geändert | Die _parse_availability-Methode aktualisieren |
| Langsame CAPTCHA-Lösung | Hohe Solver-Last | Wiederholungslogik mit exponentiellem Backoff ergänzen |
Welche CAPTCHA-Typen bei Ticketseiten auftreten
In der Praxis begegnen Ihnen fast immer reCAPTCHA v2, Cloudflare Turnstile und Cloudflare-Challenge-Seiten – alle drei löst CaptchaAI regulär. Warteschlangensysteme („virtuelle Wartezimmer") sind davon getrennt: Sie sind kein CAPTCHA, sondern eine Zugangssteuerung. Ihr Monitor sollte solche Seiten erkennen und geduldig warten oder erneut versuchen; das eigentliche CAPTCHA erscheint erst danach.
Wichtig für ehrliche Erwartungen: hCaptcha und FunCaptcha (Arkose Labs) unterstützt CaptchaAI nicht, und GeeTest v4 ist als „bald verfügbar" angekündigt, aber noch nicht nutzbar. Trifft Ihr Monitor auf einen dieser Typen, hilft der Solver an dieser Stelle nicht weiter – planen Sie das in Ihrer Fehlerbehandlung ein.
Kosten: Thread-basierte Abrechnung
CaptchaAI rechnet pro gleichzeitigem Thread ab, nicht pro Lösung – jeder Plan enthält unbegrenzte Lösungen pro Thread im Abrechnungsmonat. Für einen typischen Ticket-Monitor, der ein paar Dutzend Events im 15-Minuten-Takt prüft, reicht der Einstieg locker: BASIC (15 $/Monat, 5 Threads) deckt kleine Setups ab, STANDARD (30 $/Monat, 15 Threads) gibt Luft für parallele Prüfungen mehrerer Plattformen. Ein Thread ist eine gerade laufende CAPTCHA-Lösung; sobald sie fertig ist, nimmt derselbe Thread die nächste Abfrage.
Häufige Fragen
Ist es zulässig, Ticketseiten automatisiert zu überwachen?
Das hängt von der Plattform ab. Prüfen Sie AGB und robots.txt, überwachen Sie nur Seiten, für die Sie berechtigt sind, und halten Sie die Prüffrequenz moderat. Bei Proxy-Einsatz gilt zusätzlich die DSGVO, weil IP-Adressen personenbezogene Daten sein können.
Löst CaptchaAI auch hCaptcha auf Ticketseiten?
Nein. hCaptcha und FunCaptcha werden nicht unterstützt. Ticketseiten setzen jedoch überwiegend reCAPTCHA v2, Cloudflare Turnstile und Cloudflare Challenge ein – diese Typen deckt CaptchaAI ab.
Wie verhindere ich, dass mein Monitor gesperrt wird?
Rotieren Sie Residential-Proxys, halten Sie Cookies über die Session, und dehnen Sie die Prüfintervalle. Rechenzentrums-IPs und Sekundentakt sind die häufigsten Auslöser für Blocks und für eine Flut zusätzlicher CAPTCHA-Abfragen.
Was kostet die CAPTCHA-Lösung für einen Ticket-Monitor?
Die Abrechnung läuft über Threads, nicht über Einzellösungen. BASIC (15 $/Monat, 5 Threads) genügt für kleine Monitore; wer viele Events parallel prüft, wählt STANDARD (30 $/Monat, 15 Threads) oder höher. Innerhalb eines Plans sind die Lösungen unbegrenzt.
Wie schnell erfahre ich, dass Tickets wieder verfügbar sind?
So schnell wie Ihr Prüfintervall es zulässt: Bei einem 15-Minuten-Cron liegt die maximale Verzögerung bei rund 15 Minuten. Der Alert feuert nur bei einer echten Statusänderung, nicht bei jedem Durchlauf.
Ihren CaptchaAI-API-Schlüssel holen
Registrieren Sie sich auf captchaai.com, holen Sie Ihren API-Schlüssel und binden Sie die CAPTCHA-Lösung direkt in Ihren Ticket-Monitor ein.
Verwandte Leitfäden
- reCAPTCHA v2 per API lösen
- Cloudflare Turnstile per API lösen
- CAPTCHAs in Web-Scraping-Workflows behandeln
- Wiederholungslogik mit CaptchaAI umsetzen