Indeed, LinkedIn ve Glassdoor gibi iş ilanları, otomatik erişim modellerini tespit ettiklerinde CAPTCHA'ları dağıtır. İşe alım platformları, pazar araştırmacıları ve İK analiz araçları, iş ilanı verilerini geniş ölçekte toplamak için güvenilir CAPTCHA çözümüne ihtiyaç duyar.
Büyük İş Panolarındaki CAPTCHA'lar
| platformu | CAPTCHA Türü | Tetikleyici | Mevcut Veriler |
|---|---|---|---|
| Gerçekten | reCAPTCHA v2 | Yüksek talep hacmi | İş ilanları, maaşlar |
| Cloudflare doğrulama akışı | Bot tespiti | İşler, şirket verileri | |
| Cam kapı | reCAPTCHA v2 | Kazıma tespiti | İncelemeler, maaşlar, işler |
| ZipRecruiter | Cloudflare Turnstile | Otomatik erişim | İş listeleri |
| Canavar | reCAPTCHA v2 | Sayfaları ara | İş listeleri |
| Kariyer Oluşturucu | reCAPTCHA v3 | Giriş yap, ara | İş listeleri, aramaya devam et |
CAPTCHA İşlemeli İş Panosu Kazıyıcı
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)}")
Maaş Veri Toplama
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",
)
İş Panoları için Standart Yapılandırma İpuçları
| Teknik | Neden Yardımcı Olur? |
|---|---|
| Dönüşümlü konut vekilleri | İstekleri gerçek IP'ler arasında dağıtır |
| Sayfalar arasında 3-5 saniyelik gecikmeler | İnsan tarama hızını taklit eder |
| Oturum başına tutarlı Kullanıcı Aracısı | test profil yapılandırması uyumsuzluklarını önler |
| Çerezleri kabul et | İş panoları oturumları çerezler aracılığıyla takip eder |
| Arama sırasını rastgele seç | Sıralı sayfa kalıplarından kaçının |
| Etki alanı başına 200 sayfa/day ile sınırlayın | Tespit eşiklerinin altında kalın |
Sorun giderme
| Sorun | Sebep | Düzeltme |
|---|---|---|
| Her aramada CAPTCHA | IP işaretlendi veya oran aşıldı | IP'yi değiştirin, daha uzun gecikmeler ekleyin |
| Sonuç sayfasını boşalt | Bunun yerine CAPTCHA bloğu geri döndü | Ayrıştırmadan önce CAPTCHA'yı algıla |
| "Lütfen insan olduğunuzu doğrulayın" | Bot algılama tetiklendi | Kendi sunucu altyapınız'sini + gerçekçi UA'yı kullanın |
| Maaş verileri için giriş yapılması gerekiyor | Platform geçiş içeriği | Kimliği doğrulanmış oturumu uygula |
| Tarayıcıdan farklı sonuçlar | Konum/cookie farkları | Kabul-Dil ve coğrafi proxy ile eşleş |
SSS
Günde kaç iş ilanı kazabilirim?
Dönen yerleşik proxy'ler ve uygun gecikmelerle, kalıcı CAPTCHA'lara çarpmadan alan adı başına 500-2000 sayfaya ulaşılabilir.
İş panoları kazımayı engelliyor mu?
Çoğu iş ilanı kurulunun otomatik erişimi caydırıcı şartları vardır ancak uygulama açısından farklılık gösterir. CAPTCHA'lar, CaptchaAI'nin üstlendiği birincil savunmadır.
İş panoları için en iyi proxy türü hangisidir?
Dönüşümlü konut vekilleri, maliyet ve başarı oranı açısından en iyi dengedir. Veri merkezi IP'leri sıklıkla LinkedIn ve Glassdoor tarafından engellenir.
İlgili Kılavuzlar
İş piyasası verilerini geniş ölçekte toplayın —CaptchaAI anahtarınızı alınOtomatik CAPTCHA çözümü için.