Wer Stellenanzeigen von Indeed, LinkedIn oder Glassdoor systematisch auswerten will, stößt früher oder später auf eine CAPTCHA-Sperre. Die praktikable Lösung: Ihr Scraper übernimmt Pagination und Parsing, die CAPTCHA-Abfrage geht per API an CaptchaAI. reCAPTCHA v2, reCAPTCHA v3 und Cloudflare Turnstile werden automatisch gelöst, das zurückgegebene Token fügt Ihr Code in die Anfrage ein. So bleibt die Datenerfassung stabil, auch wenn ein Portal bei hohem Anfragevolumen eine Abfrage einblendet.
Genau dieser Punkt ist für Recruiting-Plattformen, Marktforschung und HR-Analytics der Engpass: Ohne verlässliche CAPTCHA-Lösung bricht jeder Lauf ab, sobald das Portal Automatisierung vermutet. Auch Jobportale im DACH-Raum wie StepStone, Xing oder die Jobbörse der Bundesagentur für Arbeit stellen Automatisierung vor vergleichbare CAPTCHA-Hürden.
Welche CAPTCHAs Jobportale einsetzen
| Plattform | CAPTCHA-Typ | Auslöser | Verfügbare Daten |
|---|---|---|---|
| Indeed | reCAPTCHA v2 | Hohes Anfragevolumen | Stellenanzeigen, Gehälter |
| Cloudflare Challenge | Bot-Erkennung | Jobs, Unternehmensdaten | |
| Glassdoor | reCAPTCHA v2 | Scraping-Erkennung | Bewertungen, Gehälter, Jobs |
| ZipRecruiter | Cloudflare Turnstile | Automatisierter Zugriff | Stellenanzeigen |
| Monster | reCAPTCHA v2 | Suchseiten | Stellenanzeigen |
| CareerBuilder | reCAPTCHA v3 | Login, Suche | Stellenanzeigen, Lebenslaufsuche |
CaptchaAI löst reCAPTCHA v2 und v3 sowie Cloudflare Turnstile und Challenge. hCaptcha und FunCaptcha werden nicht unterstützt, treten auf Jobportalen aber kaum auf.
Job-Scraper mit automatischer CAPTCHA-Lösung
Der Ablauf pro Seite ist immer gleich:
- Seite laden und den HTML-Text auf CAPTCHA-Indikatoren prüfen.
- Bei einem Treffer den
sitekeyextrahieren und die passendemethodwählen. - Die Lösung per API abrufen und auf das Token warten.
- Die Anfrage mit dem eingefügten Token wiederholen und die Ergebnisse parsen.
Am cf-turnstile-Marker erkennt der Code automatisch, ob Cloudflare Turnstile oder reCAPTCHA vorliegt, und übermittelt entsprechend turnstile oder userrecaptcha.
import requests
import time
import re
from bs4 import BeautifulSoup
CAPTCHAAI_KEY = "YOUR_API_KEY"
CAPTCHAAI_URL = "https://ocr.captchaai.com"
def solve_captcha(method, sitekey, pageurl, **kwargs):
data = {
"key": CAPTCHAAI_KEY,
"method": method,
"googlekey": sitekey,
"pageurl": pageurl,
"json": 1,
}
data.update(kwargs)
resp = requests.post(f"{CAPTCHAAI_URL}/in.php", data=data)
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,
})
r = result.json()
if r["request"] != "CAPCHA_NOT_READY":
return r["request"]
raise TimeoutError("Solve timeout")
class JobBoardScraper:
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",
"Accept-Language": "en-US,en;q=0.9",
})
def search_jobs(self, base_url, query, location, pages=5):
"""Search job listings across multiple pages."""
all_jobs = []
for page in range(pages):
url = f"{base_url}/jobs?q={query}&l={location}&start={page * 10}"
resp = self.session.get(url, timeout=30)
# Check for CAPTCHA
if self._has_captcha(resp.text):
resp = self._solve_and_retry(resp.text, url)
if resp.status_code == 200:
jobs = self._parse_listings(resp.text)
all_jobs.extend(jobs)
print(f"Page {page + 1}: {len(jobs)} jobs found")
else:
print(f"Page {page + 1}: Request failed ({resp.status_code})")
time.sleep(3) # Rate limit
return all_jobs
def _has_captcha(self, html):
indicators = [
'data-sitekey=',
'g-recaptcha',
'cf-turnstile',
'captcha-delivery',
]
return any(ind in html.lower() for ind in indicators)
def _solve_and_retry(self, html, url):
# Try reCAPTCHA first
match = re.search(r'data-sitekey="([^"]+)"', html)
if match:
sitekey = match.group(1)
# Detect Turnstile vs reCAPTCHA
if 'cf-turnstile' in html:
token = solve_captcha("turnstile", sitekey, url)
field = "cf-turnstile-response"
else:
token = solve_captcha("userrecaptcha", sitekey, url)
field = "g-recaptcha-response"
return self.session.post(url, data={field: token})
return self.session.get(url)
def _parse_listings(self, html):
soup = BeautifulSoup(html, "html.parser")
jobs = []
for card in soup.select(".job_seen_beacon, .jobsearch-ResultsList > li"):
title_el = card.select_one("h2 a, .jobTitle a")
company_el = card.select_one(".companyName, [data-testid='company-name']")
location_el = card.select_one(".companyLocation, [data-testid='text-location']")
salary_el = card.select_one(".salary-snippet, .estimated-salary")
if title_el:
jobs.append({
"title": title_el.get_text(strip=True),
"company": company_el.get_text(strip=True) if company_el else "",
"location": location_el.get_text(strip=True) if location_el else "",
"salary": salary_el.get_text(strip=True) if salary_el else "",
"url": title_el.get("href", ""),
})
return jobs
# Usage
scraper = JobBoardScraper(
proxy="http://user:pass@residential.proxy.com:5000"
)
jobs = scraper.search_jobs(
base_url="https://jobs.example.com",
query="python developer",
location="New York",
pages=10,
)
print(f"Total jobs collected: {len(jobs)}")
Das pageurl-Feld muss exakt der Seite entsprechen, auf der das CAPTCHA erscheint – sonst weicht das gelieferte Token vom erwarteten Kontext ab und wird verworfen.
Gehaltsdaten über Titel und Standorte sammeln
Für eine Marktanalyse fragen Sie mehrere Jobtitel gegen mehrere Standorte ab und schreiben die Ergebnisse als CSV heraus. Das folgende Beispiel kombiniert Titel und Regionen und protokolliert Fehler pro Kombination, statt den ganzen Lauf abzubrechen.
import csv
def collect_salary_data(titles, locations, output_file):
"""Collect salary data across job titles and locations."""
scraper = JobBoardScraper(
proxy="http://user:pass@residential.proxy.com:5000"
)
results = []
for title in titles:
for location in locations:
try:
jobs = scraper.search_jobs(
"https://jobs.example.com",
title, location, pages=3,
)
salaries = [j["salary"] for j in jobs if j["salary"]]
results.append({
"title": title,
"location": location,
"listings": len(jobs),
"with_salary": len(salaries),
"salary_samples": "; ".join(salaries[:5]),
})
time.sleep(5)
except Exception as e:
results.append({
"title": title,
"location": location,
"error": str(e),
})
with open(output_file, "w", newline="") as f:
writer = csv.DictWriter(
f, fieldnames=["title", "location", "listings",
"with_salary", "salary_samples", "error"],
)
writer.writeheader()
writer.writerows(results)
return results
# Collect salary data for market analysis
collect_salary_data(
titles=["Data Engineer", "ML Engineer", "DevOps Engineer"],
locations=["San Francisco", "New York", "Austin", "Remote"],
output_file="salary_data.csv",
)
Fragen Sie viele Titel und Standorte parallel ab, skaliert der Durchsatz mit der Zahl gleichzeitiger Threads. CaptchaAI rechnet pro Thread ab – nicht pro Lösung – bei unbegrenzten Lösungen je Thread. Für parallele Läufe reicht oft STANDARD (30 $/Monat, 15 Threads); wer viele Portale gleichzeitig bedient, greift zu ADVANCE (90 $/Monat, 50 Threads).
Stabile Anfrage-Muster statt ständiger CAPTCHA-Sperren
Ein sauber getakteter Scraper löst nicht nur mehr CAPTCHAs, er provoziert von vornherein weniger. Die folgenden Praktiken halten die Serverlast niedrig und die Erfolgsquote hoch:
- Rotierende Residential-Proxys verteilen Anfragen über echte IP-Adressen.
- 3–5 Sekunden Pause zwischen Seiten entsprechen menschlicher Surfgeschwindigkeit und entlasten den Server.
- Konsistenter User-Agent pro Sitzung vermeidet widersprüchliche Browser-Signale.
- Cookies akzeptieren, da Jobportale Sitzungen über Cookies verwalten.
- Suchreihenfolge variieren, um streng sequentielle Seitenaufrufe zu vermeiden.
- Maximal 200 Seiten pro Tag und Domain, damit die Last niedrig bleibt und Server-Grenzen respektiert werden.
Rechtliche Einordnung im DACH-Raum
Beim Scraping von Jobportalen fallen häufig personenbezogene Daten an: Ansprechpartner in Stellenanzeigen, teils Gehaltsangaben, und schon die verarbeiteten Proxy-IP-Adressen gelten nach DSGVO als personenbezogen. Prüfen Sie vor dem Projekt Ihre Rechtsgrundlage und die Nutzungsbedingungen des jeweiligen Portals, beschränken Sie die Erfassung auf das, was Sie tatsächlich brauchen, und dokumentieren Sie Ihren Datenfluss. CaptchaAI löst dabei ausschließlich die CAPTCHA-Abfrage – die rechtliche Bewertung Ihres Anwendungsfalls bleibt bei Ihnen.
Hinweis: Gehaltsangaben und Kontaktdaten aus öffentlichen Anzeigen bleiben personenbezogene Daten. Datenminimierung und eine dokumentierte Rechtsgrundlage sind im DACH-Raum kein Nice-to-have, sondern Voraussetzung.
Typische Probleme und Lösungen
- CAPTCHA bei jeder Suche: Die IP-Adresse ist markiert oder die Rate überschritten – IP wechseln und die Pausen verlängern.
- Leere Ergebnisseite: Statt Inhalt kam ein CAPTCHA-Block zurück – das CAPTCHA vor dem Parsen erkennen.
- „Bitte bestätigen Sie, dass Sie ein Mensch sind": Die Bot-Erkennung wurde ausgelöst – Residential-Proxy plus realistischen User-Agent verwenden.
- Anmeldung für Gehaltsdaten nötig: Das Portal blendet Inhalte hinter dem Login aus – eine authentifizierte Sitzung implementieren.
- Andere Ergebnisse als im Browser: Abweichungen bei Standort und Cookies – Accept-Language und Geo-Proxy angleichen.
Häufige Fragen
Ist das Scraping von Jobbörsen in Deutschland erlaubt?
Das hängt vom Einzelfall ab. Die meisten Portale untersagen automatisierten Zugriff in ihren AGB, und beim Verarbeiten personenbezogener Daten greift die DSGVO. Klären Sie Rechtsgrundlage und Nutzungsbedingungen vorab; CaptchaAI übernimmt ausschließlich die technische CAPTCHA-Lösung.
Welche CAPTCHA-Typen treten auf Jobportalen auf?
Überwiegend reCAPTCHA v2 und v3 sowie Cloudflare Turnstile und Challenge. CaptchaAI löst alle vier. hCaptcha wird nicht unterstützt, kommt auf Jobbörsen aber kaum vor.
Wie viele Threads benötige ich für paralleles Scraping?
So viele, wie Sie Anfragen gleichzeitig lösen wollen. Ein Thread bearbeitet eine CAPTCHA-Abfrage; ist sie fertig, nimmt er die nächste. STANDARD (30 $/Monat) bietet 15 Threads, ADVANCE (90 $/Monat) 50 – jeweils mit unbegrenzten Lösungen pro Thread.
Warum erscheint bei jeder Anfrage ein CAPTCHA?
Meist ist die IP-Adresse markiert oder die Anfragerate zu hoch. Wechseln Sie auf rotierende Residential-Proxys, verlängern Sie die Pausen zwischen Seiten und halten Sie User-Agent und Accept-Language pro Sitzung konsistent.
Verwandte Leitfäden
- Proxy-Authentifizierung richtig konfigurieren
- Höhere Lösungsraten durch bessere Proxy-Qualität
- Sticky- vs. rotierende Sitzungen
Erfassen Sie Arbeitsmarktdaten zuverlässig – holen Sie sich Ihren CaptchaAI-Schlüssel und lösen Sie reCAPTCHA und Turnstile automatisch.