Indeed’den bir iş unvanını elektronik tabloya yaklaşık ellinci kez kopyalayıp yapıştırırken, kariyer tercihlerimi sorgulamaya başladım. Eğer bir süredir Indeed’den programatik olarak yapılandırılmış veri çekmeye çalışıyorsanız, espriyi zaten biliyorsunuzdur: 403 hatası bir bug değil — Indeed’in savunma sisteminin bir özelliği.
Indeed, dünyanın en büyük iş ilanı platformu; yaklaşık 350 milyon aylık tekil ziyaretçiye, herhangi bir anda 130 milyon ilan ve 60’tan fazla ülkede operasyonlara sahip. Bu da onu gezegendeki en zengin iş piyasası veri kaynaklarından biri — ve kazınması en zor platformlardan biri — yapıyor. Açık kaynaklı kazıyıcı JobFunnel (binlerce GitHub yıldızı), anti-bot silahlanma yarışını yıllarca kaybettikten sonra Aralık 2025’te bakımını yapan kişi tarafından arşivlendi. Bakım yapan kişinin kendi sözleriyle: "Tüm kullanıcılar bazı işleri kazıyabiliyor, ancak kısa sürede captcha ile karşılaşıyor ve kazıma başarısız oluyor, sonuçta hiç iş verisi elde edilemiyor." Başka bir katkı sağlayan kişi ise ilk istekte bile CAPTCHA aldığını bildirdi. Yani evet — bu, sıradan bir kazıma hedefi değil. Bu rehberde, Python ile Indeed’i kazımak için uygulanabilir tüm yöntemleri adım adım ele alacağım, 403 engelini nasıl aşabileceğinizi göstereceğim ve — eğer hata ayıklamayı tamamen atlamak isteyenlerdenseniz — Thunderbit kullanarak kod yazmadan bir alternatif sunacağım.
Python ile Indeed’i Kazımak Ne Anlama Gelir?
Web kazıma, özünde web sayfalarından yapılandırılmış veriyi otomatik olarak çekme işlemidir. Python ile Indeed’i kazımaktan söz ettiğimizde, Indeed’in arama sonuçları ve iş detay sayfalarını ziyaret eden, alttaki HTML’i (veya gömülü veriyi) okuyan ve iş unvanı, şirket, konum, maaş ve açıklama gibi alanları kullanılabilir bir formata — CSV, veritabanı, Google E-Tablosu — aktaran bir betik yazmayı kastediyoruz.
Genellikle kullanılan Python kütüphaneleri arasında Requests (HTTP çağrıları için), BeautifulSoup (HTML ayrıştırma için) ve Selenium veya Playwright (tarayıcı otomasyonu için) bulunur. Ancak Indeed basit, statik bir site değildir. Cloudflare Bot Management ile korunan, içine gömülü bir JSON durum bloğu olan, sunucu tarafında üretilmiş HTML ve dinamik içerikten oluşan hibrit bir yapıdır. Bu da kazıyıcınızın, tek bir iş unvanını ayrıştırmadan önce bile JavaScript ile oluşturulan içerikle, dönen CSS sınıf adlarıyla ve agresif anti-bot korumalarıyla başa çıkması gerektiği anlamına gelir.
Ayrıca 2026’da resmi, ücretsiz ve yalnızca okumaya açık bir Indeed API’si de yok. Eski Publisher Jobs API yaklaşık 2020’de kullanımdan kaldırıldı; geriye kalanlar ise yalnızca işveren tarafına açık olan özellikler (Job Sync, Sponsored Jobs). Dolayısıyla geriye iki gerçekçi seçenek kalıyor: kazıma yapmak ya da üçüncü taraf bir veri sağlayıcısına ödeme yapmak.
Neden Indeed İş Verisi Kazınır?
Indeed verisini kazımak için iş gerekçesi oldukça basit: binlerce ilanı manuel olarak tek tek gezmek pratik değildir ve bu ilanların içindeki veriler gerçekten değerlidir.

| Kullanım Senaryosu | Kimlere Fayda Sağlar | Örnek |
|---|---|---|
| Potansiyel müşteri oluşturma | Satış ve işe alım ekipleri | İletişim bilgileriyle birlikte işe alan şirket listeleri oluşturma |
| İş piyasası araştırması | Analistler, İK ekipleri | Trend olan becerileri, bölgeye göre maaş kıstaslarını belirleme |
| Rekabet istihbaratı | İşverenler, personel temin ajansları | Rakiplerin işe alım trendlerini ve maaş tekliflerini izleme |
| Kişisel iş arama otomasyonu | İş arayanlar | Kriterlerinize uyan ilanları farklı konumlarda toplama |
| ML modelleri için eğitim verisi | Veri bilimciler | Tarihsel iş verisinden maaş tahmin modelleri oluşturma |
Indeed Hiring Lab’in kendi araştırması, ilan verilerinin BLS JOLTS ile yakından örtüştüğünü ve ABD iş gücü piyasası koşulları için neredeyse gerçek zamanlı bir gösterge olarak kullanılabileceğini doğruluyor. Hedge fonları, ilan hacmindeki değişimi alternatif bir veri sinyali olarak kullanıyor. İK ekipleri, kazınmış maaş aralıklarıyla ücretleri karşılaştırıyor. İşe alım uzmanları ise aktif olarak işe alan şirketlerden aday listeleri çıkarıyor.
Pratik bir not: Indeed’de maaş verisi gelişiyor ama hâlâ eksik. 2025 ortası itibarıyla ABD ilanlarının yaklaşık yüzde 59’u maaş bilgisi içeriyor, ancak yalnızca yaklaşık yüzde 22’si kesin rakam veriyor — geri kalanı aralık şeklinde. Indeed verisiyle yapılan her maaş analizinin bu eksikliği hesaba katması gerekir.
Python ile Indeed’i Kazımak İçin Yönteminizi Seçmek
Indeed’i kazımak için tek ve “doğru” bir yol yok. En iyi yaklaşım; beceri seviyenize, ne kadar veri gerektiğine ve ne kadar bakım yükü üstlenmek istediğinize bağlı. Dört ana yaklaşımı da denedim; karşılaştırma şöyle:
| Ölçüt | BS4 + Requests | Selenium | Gizli JSON (window.mosaic) | Kodsuz (Thunderbit) |
|---|---|---|---|---|
| Zorluk | Başlangıç seviyesi | Orta seviye | Orta-ileri seviye | Yok (2 tık) |
| Hız | Hızlı | Yavaş (tarayıcı render) | Hızlı | Hızlı (bulut kazıma) |
| JS ile oluşturulan içerik | Hayır | Evet | Evet (gömülü veri) | Evet |
| Anti-bot dayanıklılığı | Düşük | Orta (tespit edilebilir) | Orta-yüksek | Yüksek (otomatik yönetilir) |
| HTML değiştiğinde bakım | Yüksek (seçiciler bozulur) | Yüksek | Orta (JSON yapısı daha stabil) | Yok (AI uyum sağlar) |
| En uygun kullanım | Hızlı prototipler | Dinamik sayfalar, giriş gerektiren içerik | Toplu yapılandırılmış veri | Geliştirici olmayanlar, hızlı sonuç |
Bu rehber her yöntemi tek tek ele alıyor. Python geliştiricisiyseniz, BS4, Gizli JSON ve Selenium bölümlerine bakmak isteyeceksiniz. Kod yazmayan biriyseniz ya da 403 hatalarını debug etmekten yorulduysanız, Thunderbit bölümüne doğrudan geçebilirsiniz.
Başlamadan Önce
- Zorluk: Başlangıçtan orta seviyeye (Python bölümleri); yok (Thunderbit bölümü)
- Gerekli Süre: Python kurulumu ve ilk kazıma için yaklaşık 20–60 dakika; Thunderbit ile yaklaşık 2 dakika
- Gerekenler: Python 3.9+, bir kod editörü, Chrome tarayıcısı ve (kodsuz yol için) Thunderbit Chrome Uzantısı
Indeed Kazıma İçin Python Ortamınızı Kurma
Herhangi bir kazıma kodu yazmadan önce ortamınızı hazırlayın.
Gerekli Kütüphaneleri Kurun
Bir sanal ortam oluşturun ve ihtiyaç duyacağınız paketleri yükleyin:
python -m venv indeed_env
source indeed_env/bin/activate # Windows'ta: indeed_env\Scripts\activate
# HTTP + ayrıştırma yaklaşımı için
pip install requests beautifulsoup4 lxml httpx
# Gizli JSON yaklaşımı için (önerilen)
pip install curl_cffi parsel tenacity
# Tarayıcı otomasyonu yaklaşımı için
pip install selenium
Birkaç not:
curl_cffi, 2026’da Cloudflare korumalı siteleri kazımak için varsayılan tercih haline geldi. Gerçek tarayıcı TLS parmak izlerini taklit eder; düzrequestsvehttpxbunu yapamaz. Bunun neden önemli olduğunu anti-bot bölümünde daha detaylı anlatacağım.- Selenium 4.6+, Selenium Manager ile birlikte gelir; bu yüzden artık ChromeDriver’ı elle indirmeniz gerekmez — tarayıcı ikilisini otomatik yönetir.
- BeautifulSoup için ayrıştırma arka ucu olarak
lxmlkullanın. Standart kütüphanedekihtml.parser’dan yaklaşık 1,5 kat daha hızlıdır.
Proje Yapınızı Oluşturun
Basit tutun:
indeed_scraper/
├── scraper.py
├── requirements.txt
└── output/
Aşağıdaki tüm kod örnekleri scraper.py üzerinde ilerleyecek.
BeautifulSoup Kullanarak Python ile Indeed Nasıl Kazınır?
Bu, başlangıç dostu yaklaşım: sayfayı almak için requests, HTML’i ayrıştırmak için BeautifulSoup kullanırsınız. Kurulumu en hızlı olandır, ama Indeed’de en kırılgan yöntem de budur.
Adım 1: Indeed Arama URL’sini Oluşturun
Indeed’in arama URL’leri öngörülebilir bir desen izler:
https://www.indeed.com/jobs?q=<query>&l=<location>&start=<offset>
Örneğin, ilk sayfadan başlayarak Austin, TX için “data analyst” araması:
from urllib.parse import urlencode
params = {
"q": "data analyst",
"l": "Austin, TX",
"start": 0,
}
url = f"https://www.indeed.com/jobs?{urlencode(params)}"
print(url)
# https://www.indeed.com/jobs?q=data+analyst&l=Austin%2C+TX&start=0
Indeed sonuçları 10’ar 10’ar sayfalar ve 1.000 sonuçluk kesin bir üst sınır uygular (start <= 990). 990’ın üzerindeki herhangi bir değer sessizce aynı sayfayı döndürür.
Adım 2: Uygun Başlıklarla HTTP İsteği Gönderin
Indeed, varsayılan Python user-agent dizelerini içeren istekleri anında engeller. Gerçekçi başlıklar gerekir:
import requests
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/145.0.0.0 Safari/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",
"Referer": "https://www.indeed.com/",
}
response = requests.get(url, headers=headers, timeout=30)
print(response.status_code)
200 dönerse, şimdilik giriş yapmışsınız demektir. 403 alırsanız, Cloudflare sizi yakalamıştır. (Bundan nasıl kurtulacağınızı aşağıda anlatıyorum.)
Adım 3: HTML’den İş İlanlarını Ayrıştırın
İş kartı öğelerini seçmek için BeautifulSoup kullanın. data-testid özniteliklerini hedefleyin — bunlar, Indeed’in rastgeleleştirilmiş CSS sınıf adlarından daha stabildir:
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, "lxml")
cards = soup.find_all("div", attrs={"data-testid": "slider_item"})
jobs = []
for card in cards:
title_el = card.find("h2", class_="jobTitle")
title = title_el.get_text(strip=True) if title_el else None
company = card.find(attrs={"data-testid": "company-name"})
location = card.find(attrs={"data-testid": "text-location"})
link = title_el.find("a")["href"] if title_el and title_el.find("a") else None
jobs.append({
"title": title,
"company": company.get_text(strip=True) if company else None,
"location": location.get_text(strip=True) if location else None,
"url": f"https://www.indeed.com{link}" if link else None,
})
print(f"{len(jobs)} iş bulundu")
Adım 4: Sayfalandırmayı Yönetin
start parametresini artırarak sayfalar arasında döngü kurun:
import time, random
all_jobs = []
for page in range(0, 50, 10): # İlk 5 sayfa
params["start"] = page
url = f"https://www.indeed.com/jobs?{urlencode(params)}"
response = requests.get(url, headers=headers, timeout=30)
# ... yukarıdaki gibi ayrıştırın ...
all_jobs.extend(jobs)
time.sleep(random.uniform(3, 6))
Bu Yaklaşımın Sınırlamaları
Açık konuşayım: BS4 + Requests, 2026’da Indeed için en zayıf yöntemdir. Düz requests, Python’un standart kütüphanesindeki TLS kitaplığını kullanır; bu da Cloudflare’ın anında “tarayıcı değil” diye tanımladığı bir JA3 parmak izi üretir. Ayrıca Indeed’in sunduğu HTTP/2 desteğini de kullanmaz. Muhtemelen birkaç sayfadan sonra engelleneceksiniz. Peki ya CSS seçiciler? Indeed, css-1m4cuuf ve jobsearch-JobComponent-embeddedBody-1n0gh5s gibi sınıf adlarını sık sık değiştiriyor — bu sınıfları hedefleyen her seçici bir saatli bomba gibi.
Bu yöntemi, tek bir sayfada hızlı prototip oluşturmak için kullanın. Ölçekli işler için gizli JSON yaklaşımına geçin.
Gizli JSON Verisini Kullanarak Python ile Indeed Nasıl Kazınır?
Bu, çoğu Python geliştiricisine önerdiğim yöntemdir. Kırılgan HTML öğelerini ayrıştırmak yerine, Indeed sayfa kaynağına gömülü bir JavaScript değişkeninden yapılandırılmış veri çıkarırsınız: window.mosaic.providerData["mosaic-provider-jobcards"].
İlginizi çeken her alan — iş unvanı, şirket, konum, maaş, iş anahtarı, ilan tarihi, uzaktan çalışma işareti — bu JSON bloğunda zaten bulunur. JavaScript çalıştırmaya gerek yoktur. Şema en az 2023’ten beri sabit kaldığı için, DOM seçicilerden çok daha dayanıklıdır.
Adım 1: Sayfa HTML’ini Çekin
requests yerine curl_cffi kullanın — gerçek tarayıcı TLS parmak izlerini taklit eder; bu da Cloudflare’dan sağ çıkmak için kritiktir:
from curl_cffi import requests as cffi_requests
response = cffi_requests.get(
"https://www.indeed.com/jobs?q=python+developer&l=Remote&start=0",
impersonate="chrome124",
headers={
"Accept-Language": "en-US,en;q=0.9",
"Referer": "https://www.indeed.com/",
},
timeout=30,
)
print(response.status_code, len(response.text))
Neden curl_cffi? Çünkü bu kütüphane, curl-impersonate üzerine kuruludur ve gerçek tarayıcıların tam TLS ClientHello, HTTP/2 SETTINGS çerçevesi ve başlık sıralamasını yeniden üretir. Tek bir çağrıda hem JA3/JA4’ü hem de Akamai H2 parmak izini aşabilen, aktif olarak bakımı yapılan tek Python HTTP istemcisidir. Desteklenen taklit hedefleri arasında chrome120, chrome124, chrome131, Safari ve Edge varyantları bulunur.
Adım 2: JSON’u Bir Düzenli İfade ile Çıkarın
JSON bloğu bir <script> etiketinin içine gömülüdür. Bunu bir regex ile ayıklayın:
import re, json
MOSAIC_RE = re.compile(
r'window\.mosaic\.providerData\["mosaic-provider-jobcards"\]=(\{.+?\});',
re.DOTALL,
)
match = MOSAIC_RE.search(response.text)
if match:
data = json.loads(match.group(1))
results = data["metaData"]["mosaicProviderJobCardsModel"]["results"]
print(f"Gizli JSON içinde {len(results)} iş bulundu")
else:
print("Gizli JSON bulunamadı — engel veya sayfa değişikliği olabilir")
Adım 3: İş Alanlarını JSON’dan Ayrıştırın
results içindeki her öğe, sayfada görünenden daha fazla veri içerir:
jobs = []
for job in results:
jobs.append({
"jobkey": job["jobkey"],
"title": job["title"],
"company": job.get("company"),
"location": job.get("formattedLocation"),
"remote": job.get("remoteLocation"),
"salary": (job.get("salarySnippet") or {}).get("text"),
"posted": job.get("formattedRelativeTime"),
"job_type": job.get("jobTypes"),
"easy_apply": job.get("indeedApplyEnabled"),
"url": f"https://www.indeed.com/viewjob?jk={job['jobkey']}",
})
JSON çoğu zaman maaş tahminlerini, taksonomi özniteliklerini (beceri etiketleri) ve render edilen HTML’de her zaman görünmeyen şirket puanlarını da içerir.
Adım 4: Birden Fazla Sayfayı Kazıyın
Toplam sonuç sayısını anlamak için JSON içindeki tierSummaries alanını kullanın, sonra döngü kurun:
import time, random
all_jobs = []
for start in range(0, 50, 10): # İlk 5 sayfa
url = f"https://www.indeed.com/jobs?q=python+developer&l=Remote&start={start}&sort=date"
response = cffi_requests.get(
url,
impersonate="chrome124",
headers={"Accept-Language": "en-US,en;q=0.9", "Referer": "https://www.indeed.com/"},
timeout=30,
)
match = MOSAIC_RE.search(response.text)
if match:
data = json.loads(match.group(1))
results = data["metaData"]["mosaicProviderJobCardsModel"]["results"]
all_jobs.extend([{
"jobkey": j["jobkey"],
"title": j["title"],
"company": j.get("company"),
"location": j.get("formattedLocation"),
"salary": (j.get("salarySnippet") or {}).get("text"),
"url": f"https://www.indeed.com/viewjob?jk={j['jobkey']}",
} for j in results])
time.sleep(random.uniform(3, 7))
print(f"Toplam: {len(all_jobs)} iş kazındı")
Gizli JSON Neden Daha Dayanıklıdır?
window.mosaic.providerData yapısı, CSS sınıf adlarına göre daha seyrek değişir. Karmaşık HTML’i ayrıştırmadan temiz ve yapılandırılmış veri elde edersiniz. Yine de anti-bot önlemlerine (başlıklar, gecikmeler, proxy’ler) ihtiyacınız olur — bunu bir sonraki bölümde ele alacağız.
Selenium Kullanarak Python ile Indeed Nasıl Kazınır?
Selenium, tarayıcı otomasyonu yaklaşımıdır. Sayfayla etkileşime girmeniz gerekiyorsa — iş detay panellerine tıklamak, giriş gerektiren içerikleri işlemek veya ilk HTML’de olmayan, sonradan yüklenen açıklamaları kazımak gibi — yararlıdır.
HTTP İstemcileri Yerine Ne Zaman Selenium Kullanılır?
- Indeed bazı içerikleri dinamik olarak yüklüyorsa (sağdaki panelde tam iş açıklamaları)
- Oturum durumuna veya girişe ihtiyaç duyan sayfaları kazımanız gerekiyorsa
- Hızın kritik olmadığı küçük ölçekli kazımalar yapıyorsanız
Hızlı Bir Uygulama
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import time
options = Options()
options.add_argument("--disable-blink-features=AutomationControlled")
# options.add_argument("--headless=new") # Headless daha kolay tespit edilir — dikkatli kullanın
driver = webdriver.Chrome(options=options)
driver.get("https://www.indeed.com/jobs?q=data+engineer&l=New+York")
time.sleep(3)
cards = driver.find_elements(By.CSS_SELECTOR, "[data-testid='slider_item']")
for card in cards:
try:
title = card.find_element(By.CSS_SELECTOR, "h2.jobTitle").text
company = card.find_element(By.CSS_SELECTOR, "[data-testid='company-name']").text
location = card.find_element(By.CSS_SELECTOR, "[data-testid='text-location']").text
print(f"{title} | {company} | {location}")
except Exception:
continue
driver.quit()
Sınırlamalar
Selenium yavaştır — her sayfa tam tarayıcı renderı gerektirir. Headless Chrome, Indeed’in anti-bot sistemi tarafından tespit edilebilir (Cloudflare navigator.webdriver, WebGL üretici dizelerini, eklenti sayılarını ve daha fazlasını kontrol eder). undetected-chromedriver bile tespiti yalnızca erteler; kalıcı olarak engellemez. Ve BS4’de olduğu gibi, Indeed arayüzünü güncellediğinde seçicileriniz bozulur.
Çoğu kullanım senaryosunda gizli JSON yaklaşımı size aynı veriyi daha hızlı ve daha az bakım yüküyle sağlar. Gerçekten bir tarayıcıya ihtiyacınız olan özel durumlar için Selenium’u saklayın.
Python ile Indeed Kazırken 403 Hatalarından Nasıl Kaçınılır?
En önemli bölüm burası. Eğer buraya sinir bozucu bir Google aramasından geldiyseniz, doğru yerdesiniz.

Indeed Neden Kazıyıcınızı Engeller?
Indeed, Cloudflare Bot Management ile Cloudflare Turnstile kullanır — DataDome değil, PerimeterX değil. Yanıt başlıkları bunu doğrular: server: cloudflare, cf-ray ve __cf_bm bot yönetimi çerezi. Cloudflare, TLS parmak izinizi (JA3/JA4), HTTP/2 başlık sıralamanızı, istek örüntülerinizi ve tarayıcı davranış sinyallerinizi inceler. Bunlardan herhangi biri insan dışı görünürse, 403, 429, 503 ya da — en sinsi senaryo — gerçek iş verisi yerine Turnstile doğrulama sayfası içeren bir 200 OK alırsınız.
User-Agent ve İstek Başlıklarını Döndürün
Tek ve sabit bir User-Agent kullanmak, engellenmenin en hızlı yoludur. Güncel ve gerçekçi dizelerden oluşan bir havuzdan döndürün. Önemli not: User-Agent Reduction’dan beri Chrome’un küçük sürüm alanları 0.0.0’a sabitlendi — sıfır olmayan uydurma küçük sürüm numaraları üretmeyin, yoksa anti-bot sistemleri sizi işaretler.
import random
USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36 Edg/145.0.3800.97",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 "
"(KHTML, like Gecko) Version/17.4 Safari/605.1.15",
]
headers = {
"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, zstd",
"Referer": "https://www.indeed.com/",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
}
Ayrıca sec-ch-ua Client Hint’lerinin UA sürümüyle eşleştiğinden emin olun. Chrome 145 olduğunu iddia eden bir User-Agent’ın yanında sec-ch-ua: "Chrome";v="131" görmek, anında kırmızı bayraktır.
İstekler Arasına Rastgele Gecikmeler Ekleyin
Sabit aralıklar, örüntü tespitiyle işaretlenir. Rastgele sapmalar kullanın:
import time, random
# Her isteğin arasında
time.sleep(random.uniform(3, 6))
# Engelden sonra yeniden deneme gecikmesi
def backoff_sleep(attempt):
base = 4
sleep_time = base * (2 ** attempt) + random.uniform(0, 2)
time.sleep(min(sleep_time, 60))
ScrapeOps ve WebScraping.AI kaynaklarındaki ortak görüş, IP başına istekler arasında 3–6 saniyelik bekleme ve bir oturumda IP başına yaklaşık 100 isteği aşmadan önce rotasyon yapmaktır.
Proxy Rotasyonu Kullanın
Başarıyı belirleyen en büyük unsur budur. AWS/GCP aralığındaki veri merkezi proxy’leri, Cloudflare Enterprise hedeflerinde yaklaşık yüzde 5–15 başarı sağlar — Indeed’de pratikte kullanılamazdır. Residential proxy’ler ve doğru TLS parmak izi ile başarı oranı yüzde 80–95’e çıkabilir.
PROXIES = [
"http://user:pass@us.residential.example:7777",
"http://user:pass@us.residential.example:7778",
"http://user:pass@us.residential.example:7779",
]
proxy = random.choice(PROXIES)
response = cffi_requests.get(
url,
impersonate="chrome124",
headers=headers,
proxies={"https": proxy},
timeout=30,
)
2026’da residential proxy fiyatları, sağlayıcıya ve taahhüt düzeyine bağlı olarak yaklaşık GB başına 4–8,50 dolar aralığındadır. Indeed özelinde, küçük bir havuzla başlayın ve gerektiğinde ölçeklendirin.
403, 429 ve 503 Durum Kodlarını Zarifçe Yönetin
Sadece körlemesine yeniden denemeyin. Farklı durum kodları farklı anlamlar taşır:
def fetch_with_retry(url, proxy_pool, max_retries=5):
for attempt in range(max_retries):
proxy = random.choice(proxy_pool)
headers["User-Agent"] = random.choice(USER_AGENTS)
try:
r = cffi_requests.get(
url,
impersonate=random.choice(["chrome124", "chrome120", "edge101"]),
headers=headers,
proxies={"https": proxy},
timeout=30,
)
# Sinsi "200 ama challenge var" durumunu kontrol et
if r.status_code == 200 and "cf-turnstile" not in r.text and "Just a moment" not in r.text:
return r
if r.status_code == 403:
print(f"403 — engellendi. Proxy değiştiriliyor, deneme {attempt + 1}")
elif r.status_code == 429:
print(f"429 — hız limiti aşıldı. Yavaşlatılıyor.")
elif r.status_code == 503:
print(f"503 — sunucu aşırı yüklü veya JS doğrulaması var.")
backoff_sleep(attempt)
except Exception as e:
print(f"İstek hatası: {e}")
backoff_sleep(attempt)
raise RuntimeError(f"{max_retries} yeniden deneme sonrası başarısız: {url}")
200-with-challenge durumu en zor olanıdır. 200’ü başarı saymadan önce yanıt gövdesinde mutlaka cf-turnstile veya Just a moment işaretlerini arayın.
Daha Kolay Alternatif: Anti-Bot İşini Thunderbit’e Bırakın
Proxy havuzları kurmak, başlık rotasyonu yapmak ve TLS parmak izi taklidiyle uğraşmak istemeyen kullanıcılar için, Thunderbit’in bulut kazıması CAPTCHA’ları, proxy rotasyonunu ve anti-bot korumalarını otomatik olarak yönetir. Proxy kurulumu yok, curl_cffi yapılandırması yok, CAPTCHA çözme kütüphaneleri yok. Veriyi sadece hızlıca almak istiyorsanız en az dirençli yol budur.
Indeed Kazıyıcınız Neden Sürekli Bozuluyor (Ve Nasıl Düzeltilir)
403 duvarı akut acıdır. Kronik acı ise bakımdır — bugün çalışan kazıyıcılar, gelecek hafta sessizce boş veri veya eski sonuçlar döndürebilir.
Indeed Seçicilerinizi Nasıl Bozar?
Indeed, CSS sınıf adlarını agresif biçimde döndürür. Bright Data’nın rehberi açıkça uyarıyor ki css-1m4cuuf ve css-1rqpxry gibi sınıflar “rastgele üretilmiş görünüyor — büyük olasılıkla derleme zamanında.” A/B testleri, farklı oturumların farklı sayfa düzenleri görmesine neden olur. DOM yeniden yapılandırmaları da önceden haber verilmeden gerçekleşir.
JobFunnel hikâyesi öğreticidir. Bir katkı sağlayan kişi şöyle raporladı: "CaptchaBuster captcha’yı başarıyla azalttı ve sayfayı hâlâ başarıyla kazıyamamamızın nedeni [eski] BeautifulSoup seçicileriydi." Kazıyıcı engellenmemişti — yanlış öğeleri ayrıştırıyordu.
Strateji: DOM Ayrıştırma Yerine Gizli JSON’u Tercih Edin
window.mosaic.providerData bloğu en az 2023’ten beri şema açısından stabildir. metaData.mosaicProviderJobCardsModel.results[] yolu 2026’da da hâlâ kanonik durumdadır. DOM seçiciler aylık olarak bozulur. JSON çıkarımı ise — hiç bozulmasa da — yılda bir bozulur.
Strateji: Sınıf Adları Yerine Veri Özniteliklerini Kullanın
DOM’a dokunmanız gerektiğinde işlevsel öznitelikleri hedefleyin:
| Seçici | Amaç |
|---|---|
[data-testid="slider_item"] | Her iş kartı kapsayıcısı |
[data-testid="job-title"] veya h2.jobTitle > a | İş unvanı bağlantısı |
[data-testid="company-name"] | İşveren adı |
[data-testid="text-location"] | Konum metni |
Her kartta data-jk="<jobkey>" | En kararlı kanca — 2019’dan beri değişmedi |
Eski Seçicileri Tespit Etmek İçin Doğrulama Kontrolleri Ekleyin
Kazıyıcınızın sessizce sıfır sonuçla çalışmasına asla izin vermeyin. Her çekimden sonra bir kontrol ekleyin:
results = parse_hidden_json(html)
assert len(results) > 0, (
f"Indeed start={start} için boş sonuç kümesi döndürdü — "
"muhtemel engel, CAPTCHA veya seçici kayması. "
f"Yanıtın ilk 500 karakteri: {html[:500]}"
)
Hata durumunda ham yanıtın ilk 500–2000 karakterini kaydedin. Böylece Turnstile challenge, giriş duvarı veya şema değişikliği alıp almadığınızı hemen anlarsınız. Her gün sabit bir sorguya karşı (örneğin q=python&l=remote) sıfırdan farklı sonuç bekleyen bir CI düzeyinde smoke test çalıştırın.
AI Alternatifi: Hiç Bozulmayan Kazıyıcılar
Thunderbit’in AI’sı sayfa yapısını her seferinde yeniden okur — sabit kodlanmış seçicilere ya da regex desenlerine dayanmaz. Indeed HTML’ini değiştirdiğinde Thunderbit otomatik olarak uyum sağlar. Bu, forum kullanıcılarının sürekli en büyük sıkıntı olarak dile getirdiği bakım yükünü doğrudan ortadan kaldırır. Eğer hiç bitmeyen “kazıyıcı yine boş satır döndürüyor” mesajlarıyla uyanmışsanız, bunun değerini bilirsiniz.
Python Yazmadan Indeed Kazımak: Kodsuz Alternatif
Rakip rehberlerin hepsi Python kodu yazacağınızı varsayar. Ama forum verileri başka bir hikâye anlatıyor. Kullanıcılar "sürekli bug ve hata olması yüzünden çok zor" gibi şeyler söylüyor, bazıları veriyi almak için Fiverr’dan birini tutmayı bile öneriyor. Bu size benziyorsa, bu bölüm sizin kaçış kapınız.
Thunderbit ile Indeed Nasıl Kazınır? (Adım Adım)
1. Adım: Chrome Web Store’dan Thunderbit Chrome Uzantısını kurun. Başlamak ücretsizdir.
2. Adım: Tarayıcınızda bir Indeed arama sonuçları sayfasına gidin — örneğin, https://www.indeed.com/jobs?q=data+analyst&l=Austin%2C+TX.
3. Adım: Tarayıcı araç çubuğunuzdaki Thunderbit simgesine tıklayın, ardından "AI Suggest Fields" düğmesine basın. Thunderbit’in AI’sı sayfayı tarar ve İş Unvanı, Şirket, Konum, Maaş, İş URL’si ve İlan Tarihi gibi sütunları otomatik olarak algılar. Önerilen alanları inceleyip düzenleyebilirsiniz — ihtiyacınız olmayan sütunları kaldırın veya ne istediğinizi düz İngilizceyle tarif ederek özel alanlar ekleyin.
4. Adım: "Scrape" düğmesine tıklayın. Thunderbit sayfadan veriyi çeker ve yapılandırılmış bir tabloda gösterir. Yapılandırdığınız alanlarla birlikte iş ilanı satırlarını görmelisiniz.
Alt Sayfa Kazıma ile Zenginleştirin
Listeleme sayfasını kazıdıktan sonra, Thunderbit’in her bir iş detay sayfasını ziyaret etmesi için "Scrape Subpages" seçeneğine tıklayın. Tam iş açıklamalarını, nitelikleri, yan hakları ve başvuru bağlantılarını çeker — ek kurulum gerekmez. Bu, her /viewjob?jk=<jobkey> URL’sine gitmek için ikinci bir Python kazıyıcısı yazmaya eşdeğerdir; farkı ise tek tıkla yapılmasıdır.
Sayfalandırmayı Otomatik Yönetin
Thunderbit, Indeed’in tıklama tabanlı sayfalandırmasını otomatik olarak yönetir. Offset URL’leri elle oluşturmanıza ya da sayfalandırma döngüleri yazmanıza gerek yoktur. Sayfaları tek tek geçer ve sonuçları birleştirir.
Favori Araçlarınıza Dışa Aktarın
Kazınan verileri CSV, Excel, Google E-Tablolar, Airtable veya Notion’a — tamamen ücretsiz — aktarın. csv.writer() ya da pandas.to_csv() kodu yazmanız gerekmez.
Ne Zaman Python, Ne Zaman Thunderbit?
| Senaryo | En İyi Araç |
|---|---|
| Özel veri hatları, cron/Airflow ile zamanlanmış otomasyon | Python |
| Daha büyük bir kod tabanına entegrasyon | Python |
| Son derece özelleştirilmiş ayrıştırma mantığı | Python |
| Tek seferlik araştırma veya pazar analizi | Thunderbit |
| Teknik olmayan ekip üyelerinin veriye ihtiyacı varsa | Thunderbit |
| 403 hatalarını debug etmeden veriyi hemen almak | Thunderbit |
| Sıfır kurulumla alt sayfa zenginleştirme | Thunderbit |
Süre karşılaştırması: Python kurulumu + anti-bot debug süreci = saatler ile günler arası (özellikle ilk denemenizde). Thunderbit = aynı veri için 2 dakikanın altında. Python yanlış demiyorum — sadece neye ihtiyacınız olduğuna bağlı olduğunu söylüyorum.
Indeed Kazımak Yasal mı? Bilmeniz Gerekenler
En üst sıradaki Indeed kazıma rehberlerinin hiçbiri hukuki duruma değinmiyor; bu, forumlarda "Indeed’i kazımak yasal mı?" sorusunun ne kadar sık sorulduğunu düşününce şaşırtıcı. Bu hukuki tavsiye değildir, ama genel tablo şöyledir.
Indeed’in Hizmet Şartları
Indeed’in Kullanım Şartları (indeed.com/legal) kapsamlı bir “kazımak yasaktır” maddesi içermez. Açık tek otomasyon yasağı, A.3.5 bölümündedir; burada "Indeed Apply sürecini otomatikleştirmek için herhangi bir otomasyon, betik veya bot kullanımı" yasaklanır. Bu dar kapsamlıdır ve halka açık iş ilanlarının pasif olarak okunmasını kapsamaz. Indeed’in ana yaptırım aracı mahkeme değil, teknik önlemlerdir — Cloudflare challenge’ları, IP banları, cihaz parmak izi tespiti.
İlgili Hukuki İçtihat
En çok atıf yapılan ABD davası hiQ Labs v. LinkedIn’dir. 9. Temyiz Mahkemesi Nisan 2022’de, herkese açık verinin kazınmasının “muhtemelen CFAA’yı (Computer Fraud and Abuse Act) ihlal etmeyeceğine” hükmetti. Ancak hiQ daha sonra, çalışanlarının sahte LinkedIn profilleri oluşturup Hizmet Şartlarını kabul etmesi nedeniyle sözleşme ihlali nedeniyle sorumlu bulundu.
Daha yakın tarihli Meta v. Bright Data (N.D. Cal., Ocak 2024) daha da net bir karar üretti. Yargıç Chen, Facebook ve Instagram’ın kullanım şartlarının “oturum kapalıyken herkese açık verilerin kazınmasını engellemediğine” hükmetti. Meta, ertesi ay kalan taleplerini gönüllü olarak geri çekti.
Indeed’in robots.txt Dosyası
Indeed’in robots.txt dosyası, varsayılan User-agent: * için genel olarak /jobs/ ve /job/ yollarını engeller; ancak Googlebot ve Bingbot’un /viewjob? — tekil iş detay sayfaları — erişimine açıkça izin verir. AI eğitim amaçlı tarayıcılar (GPTBot, CCBot, anthropic-ai) ciddi biçimde kısıtlanmıştır. robots.txt ABD’de hukuken bağlayıcı değildir; ancak buna saygı göstermek iyi niyetin kanıtı ve en iyi uygulamadır.
Sorumlu Kazıma İçin Pratik Kurallar
- Yalnızca herkese açık veriyi kazıyın — asla giriş yapmayın, sahte hesap oluşturmayın
- Hız sınırlarına uyun: IP başına 3–6 saniyede 1 istek, tek haneli eşzamanlılık
- Kazınmış veriyi kendi iş panonuzmuş gibi yeniden yayınlamayın
- Veriyi kişisel veya dahili araştırma için kullanın; izin olmadan ticari yeniden satış için değil
- İhtiyacınız olmayan PII’yi silin veya karmalayın; kişisel veriye yakın veriler için saklama üst sınırı belirleyin
- Ölçekli çalışıyorsanız veya AB/İngiltere’de faaliyet gösteriyorsanız, bir avukata danışın — GDPR Madde 14 şeffaflık yükümlülükleri kazınan kişisel veriler için geçerlidir
Risk skalası: kişisel iş arama otomasyonu düşük uçtadır. Indeed verisinin büyük ölçekli ticari yeniden satışı ise yüksek uçtadır.
Sonuç ve Önemli Çıkarımlar
Python ile Indeed’i kazımak mümkündür, ama bu “kur ve unut” tarzı bir hafta sonu projesi değildir. Indeed’in Cloudflare koruması, dönen seçicileri ve agresif anti-bot önlemleri, doğru araçlarla ve doğru beklentilerle yaklaşmanız gerektiği anlamına gelir.
Buradan çıkaracağım temel noktalar şunlar:
- Indeed, web’deki en zengin iş piyasası veri kaynaklarından biridir — 350 milyon aylık ziyaretçi, 130 milyon ilan — ama kazıyıcılara karşı sert biçimde savaşır.
- Gizli JSON çıkarımı (
window.mosaic.providerData) en dayanıklı Python yaklaşımıdır. Şema yıllardır stabildir; CSS seçiciler ise aylık olarak bozulur. - Tarayıcı taklidi yapan
curl_cffi, 2026’da Cloudflare korumalı siteler için varsayılan HTTP istemcisidir. Düzrequestsvehttpx, yalnızca TLS parmak izi nedeniyle engellenir. - 403 hatalarından kaçınmak için her zaman dönen başlıklar, rastgele gecikmeler ve residential proxy’ler kullanın. Veri merkezi proxy’leri, Cloudflare Enterprise karşısında neredeyse işe yaramaz.
- Seçiciler bozulduğunda veya iş verisi yerine bir challenge sayfası servis edildiğinde bunu hemen anlayabilmek için doğrulama kontrolleri ekleyin.
- Teknik olmayan kullanıcılar veya sadece hızlı sonuç isteyen herkes için, Thunderbit, site değişikliklerine otomatik uyum sağlayan kodsuz, AI destekli bir yol sunar — proxy yok, debug yok, bakım yok.
Kodsuz yolu denemek isterseniz, Thunderbit ücretsiz bir katman sunuyor; böylece Indeed üzerinde hiçbir taahhüt olmadan test edebilirsiniz. Python yolunu seçiyorsanız, yukarıdaki kod örnekleri sağlam bir başlangıç noktasıdır — sadece anti-bot dayanıklılığını sonradan akla gelen bir mesele değil, birinci sınıf bir gereklilik olarak ele almayı unutmayın.
Web kazıma yaklaşımları ve araçları hakkında daha fazlası için Python ile web kazıma nasıl yapılır, en iyi otomatik web kazıma araçları ve engellenmeden web kazıma rehberlerimize göz atın. Ayrıca Thunderbit YouTube Kanalı üzerindeki eğitim videolarını da izleyebilirsiniz.
Thunderbit ile Indeed Verisini Daha Hızlı Kazıyın Get Started Free
SSS
Indeed’i kazımak için en iyi Python kütüphaneleri hangileridir?
HTTP istekleri için 2026’da en güçlü seçenek curl_cffi’dir — gerçek tarayıcı TLS parmak izlerini taklit eder ve Cloudflare’ı aşmak için bu çok önemlidir. Daha az korunan hedefler için HTTP/2 destekli httpx iyi bir yedektir. HTML ayrıştırmada lxml ile BeautifulSoup4 hâlâ standarttır. Tarayıcı otomasyonu için Playwright (playwright-stealth ile) veya undetected-chromedriver çalışır, ancak her ikisi de giderek daha kolay tespit edilmektedir. Gizli JSON regex yaklaşımı (window.mosaic.providerData) ise yoğun ayrıştırma ihtiyacını tamamen ortadan kaldırır.
Indeed’i kazırken neden sürekli 403 hatası alıyorum?
Indeed, TLS parmak izinizi (JA3/JA4), HTTP/2 başlık sıralamasını, istek örüntülerini ve tarayıcı davranışını inceleyen Cloudflare Bot Management kullanır. Düz requests kullanıyorsanız, TLS parmak izinizi sizi anında bir Python betiği olarak ele verir — başlıklarınız okunmadan 403 gelir. Bunu düzeltmek için tarayıcı taklidi yapan curl_cffi’ye geçin, gerçekçi User-Agent dizelerini döndürün, rastgele gecikmeler ekleyin (3–6 saniye) ve residential proxy’ler kullanın. Ayrıca “Turnstile challenge ile gelen 200” durumunu da kontrol edin — yanıt gövdelerinde cf-turnstile işaretlerini arayın.
Kod yazmadan Indeed kazıyabilir miyim?
Evet. Thunderbit gibi araçlar, Indeed iş ilanlarını birkaç tıklamayla çekmenizi sağlar — Chrome uzantısını kurun, bir Indeed arama sayfasına gidin, "AI Suggest Fields" düğmesine tıklayın, ardından "Scrape" seçin. Thunderbit’in AI’sı iş unvanı, şirket, konum ve maaş gibi alanları otomatik algılar. Sayfalandırmayı, alt sayfa zenginleştirmeyi (tam iş açıklamaları) ve anti-bot korumalarını otomatik yönetir. CSV, Google E-Tablolar, Airtable veya Notion’a ücretsiz dışa aktarabilirsiniz.
Indeed HTML yapısını ne sıklıkla değiştiriyor?
Indeed, CSS sınıf adlarını düzenli olarak döndürür (örneğin css-1m4cuuf, rastgele hash dizeleri) ve DOM öğelerini önceden haber vermeden yeniden yapılandırır. A/B testleri, farklı kullanıcıların aynı anda farklı düzenler görmesine neden olabilir. Gizli JSON yaklaşımı (window.mosaic.providerData) çok daha stabildir — şema en az 2023’ten beri tutarlıdır. DOM seçiciler kullanmanız gerekiyorsa, CSS sınıfları yerine data-testid özniteliklerini ve data-jk (iş anahtarı) alanını hedefleyin.
Indeed’i kazımak yasal mı?
Oturumu kapalı ve herkese açık Indeed iş URL’lerini kazımak, ABD’de 9. Daire’nin hiQ v. LinkedIn kararı (2022) ve Meta v. Bright Data kararı (2024) temelinde CFAA sorumluluğu doğurma ihtimali düşük bir faaliyettir. Indeed’in kullanım şartları, genel ilanların pasif okunmasını değil, özellikle Apply sürecinin otomasyonunu yasaklar. Bununla birlikte, her zaman sorumlu davranın: giriş yapmayın, sahte hesap oluşturmayın, hız sınırlarına uyun, veriyi kendi iş panonuz gibi yeniden yayınlamayın ve kişisel verileri (işe alım uzmanı adları, e-postalar) GDPR/CCPA kapsamında dikkatle ele alın. Ticari ölçekte çalışıyorsanız bir avukata danışın.
Daha Fazla Bilgi


