Tıbbi verileri parsellemek, proxy seçimi konusunda özel bir yaklaşım gerektiren bir görevdir. Tıbbi portallar, klinik araştırma veritabanları ve ilaç kaynakları, otomatik veri toplama sistemlerine karşı gelişmiş koruma sistemleri kullanmaktadır. Bu yazıda, tıbbi bilgileri güvenli bir şekilde parsellemek için proxy'lerin nasıl doğru bir şekilde ayarlanacağı, yasaklardan nasıl kaçınılacağı ve gerekli verilerin etkili bir şekilde nasıl toplanacağı ele alınacaktır.
Tıbbi siteler neden parsellemeyi yasaklıyor
Tıbbi portallar ve veritabanları, otomatik bilgi toplama konusunda birkaç nedenle özellikle hassastır. Öncelikle, birçoğu ticari bir temele dayanmakta ve verilere ücretli abonelikler aracılığıyla erişim satmaktadır. Otomatik parselleme, kullanım şartlarını ve lisans sözleşmelerini ihlal edebilir.
İkinci olarak, tıbbi veriler genellikle yasalarla korunan gizli bilgileri içermektedir (ABD'de HIPAA, Avrupa'da GDPR). Kaynak sahipleri, bu verilere erişimi kontrol etmek ve yetkisiz dağılımını önlemekle yükümlüdür. Bu nedenle, gelişmiş koruma sistemleri kullanmaktadırlar:
- Rate limiting — bir IP adresinden belirli bir zaman diliminde (genellikle dakikada 10-50 istek) gelen istek sayısının sınırlandırılması
- Fingerprinting — tarayıcı özelliklerinin, HTTP başlıklarının ve kaynakların yüklenme sırasının analizi
- CAPTCHA — şüpheli etkinlik durumunda devreye giren reCAPTCHA v3 gibi sistemler
- IP yasakları — veri merkezlerinin IP adreslerinin geçici veya kalıcı olarak yasaklanması
- Cloudflare ve benzerleri — CDN düzeyinde botlara karşı koruma
Üçüncü neden — sunucular üzerindeki yük. Tıbbi veritabanları genellikle milyonlarca kayıt içermekte ve toplu parselleme, altyapı üzerinde önemli bir yük oluşturabilir. Bu nedenle, yöneticiler otomatik veri toplama ile aktif olarak mücadele etmekte ve botlara özgü davranış kalıplarını izlemektedir: istekler arasındaki benzer aralıklar, sayfaların lineer olarak gezilmesi, JavaScript ve çerezlerin yokluğu.
Önemli: Tıbbi verileri parsellemeye başlamadan önce, sitenin kullanım şartlarını ve geçerli yasaları mutlaka inceleyin. Bazı veriler telif hakkı ile korunabilir veya hasta kişisel bilgilerini içerebilir. Faaliyetlerinizin yasal olduğundan ve üçüncü şahısların haklarını ihlal etmediğinden emin olun.
Tıbbi veriler için hangi proxy türü seçilmeli
Proxy türünün seçimi, tıbbi verilerin başarılı bir şekilde parselenmesi için kritik öneme sahiptir. Farklı kaynaklar, farklı yaklaşımlar gerektirmektedir. Temel proxy türlerini ve uygulanabilirliklerini inceleyelim:
| Proxy Türü | Avantajları | Dezavantajları | Ne Zaman Kullanılmalı |
|---|---|---|---|
| Veri Merkezi Proxy'leri | Yüksek hız (100+ Mbps), düşük maliyet, stabil bağlantı | Kolayca tespit edilebilir, genellikle korumalı sitelerde yasaklıdır | Sıkı koruma olmayan açık veri tabanları (PubMed, WHO) |
| Konut Proxy'leri | Gerçek ev kullanıcılarının IP'leri, düşük yasaklanma riski, Cloudflare'ı geçer | Daha yüksek maliyet, değişken hız, kararsız olabilirler | Koruma altındaki ticari veri tabanları (Elsevier, Springer), Cloudflare ile siteler |
| Mobil Proxy'ler | Maksimum güvenilirlik (mobil operatörlerin IP'leri), neredeyse yasaklanmazlar | En pahalıları, sınırlı coğrafya, daha yavaş olabilirler | Özellikle korumalı kaynaklar, konut proxy'leri işe yaramadığında |
| ISP Proxy'leri | Veri merkezi hızları + konut güvenilirliği, statik IP'ler | Ortalama maliyet, sınırlı erişilebilirlik | Bir IP ile uzun süreli parselleme, stabilite gerektiğinde |
Çoğu tıbbi veri parselleme görevi için konut proxy'leri kullanılması önerilmektedir. Maliyet ve etkinlik arasında optimal bir denge sağlarlar. Veri merkezi proxy'leri yalnızca korumasız açık kaynaklar için uygundur. Mobil proxy'ler, diğer türlerin işe yaramadığı durumlarda kullanılmalıdır.
Belirli kaynaklar için seçim önerileri
- PubMed, PubMed Central — veri merkezi proxy'leri yeterlidir, ancak saniyede 3 istekle sınırlıdır
- ClinicalTrials.gov — veri merkezi proxy'leri, resmi bir API vardır
- Elsevier, Springer, Wiley — konut proxy'leri zorunludur, gelişmiş fingerprinting kullanmaktadırlar
- DrugBank, RxList — konut proxy'leri, parsellemeye karşı aktif koruma
- FDA, EMA veri tabanları — veri merkezi proxy'leri uygundur, ancak parselleme hızı düşüktür
Tıbbi verilerin ana kaynakları ve koruma yöntemleri
Tıbbi veriler, her birinin kendine özgü özellikleri ve koruma seviyeleri olan birçok kaynağa dağılmıştır. Bu özelliklerin anlaşılması, parselleme stratejisinin doğru bir şekilde ayarlanmasına yardımcı olacaktır.
Açık devlet veri tabanları
PubMed/PubMed Central — en büyük tıbbi yayın veritabanı, 35 milyondan fazla kayıt içermektedir. ABD Ulusal Tıp Kütüphanesi (NLM), verilere erişim için tercih edilen yöntem olan resmi E-utilities API'sini sağlamaktadır. Web arayüzünün doğrudan parsellemesi mümkündür, ancak bir IP'den saniyede 3 istekle sınırlıdır. Limitin aşılması, 24 saatlik geçici bir yasakla sonuçlanır.
ClinicalTrials.gov — klinik araştırmalar veritabanı, 220 ülkede 400,000'den fazla araştırma hakkında bilgi içermektedir. Ayrıca programlı erişim için API sağlamaktadır. Web arayüzü, bir IP'den 5 dakikada maksimum 100 istekle sınırlı olan rate limiting ile korunmaktadır. Temel bot koruması kullanılmakta, ancak Cloudflare yoktur.
FDA İlaç Veritabanı — FDA onaylı ilaçların veritabanı. Web arayüzü ve openFDA API'si aracılığıyla açık erişim. Sınırlamalar: anonim kullanıcılar için dakikada 240 istek, API anahtarı ile dakikada 1000 istek. Yasaklamalar nadirdir, ancak agresif parselleme durumunda mümkün olabilir.
Ticari bilimsel yayıncılar
Elsevier (ScienceDirect) — bilimsel literatürün en büyük yayıncılarından biri. Çok katmanlı koruma kullanmaktadır: Cloudflare, tarayıcı fingerprinting, kullanıcı davranış analizi. Otomatik indirme kalıplarını tespit eder: makalelere ardışık erişim, JavaScript yokluğu, alışılmadık User-Agent. Parselleme tespit edildiğinde, IP'yi hesap düzeyinde yasaklar ve tüm kurumu yasaklayabilir. Tam bir tarayıcı emülasyonu ile rotasyonlu konut proxy'lerinin kullanılması zorunludur.
Springer Nature — benzer koruma, ayrıca sayfaların kaydırma hızını ve fare hareketlerini izler. Botları tespit etmek için makine öğrenimi kullanmaktadır. Bir IP'den saatte 10-15 makaleden fazla parselleme yapılması önerilir, istekler arasında rastgele gecikmeler ile.
Wiley Online Library — daha az agresif bir koruma, ancak yine de proxy kullanımı gerektirir. Bir IP'den saatte yaklaşık 50 istek yapmaya izin verir, yasaklama olmadan. Etkinliği izlemek için oturum çerezleri kullanmaktadır.
İlaç veri tabanları
DrugBank — kapsamlı bir ilaç veri tabanı. Ücretsiz sürüm, web arayüzü ile sınırlıdır, ticari sürüm API ve veri çıkışları sunmaktadır. Web versiyonu, Cloudflare ve rate limiting ile korunmaktadır — dakikada maksimum 20 istek. Otomasyonu, çerezlerin ve JavaScript'in yokluğuna göre tespit eder.
RxList, Drugs.com — tüketiciler için popüler ilaç rehberleri. Cloudflare kullanmakta ve parsellemeye karşı aktif bir şekilde mücadele etmektedir. Veri merkezi IP'lerini neredeyse anında yasaklamaktadır. Konut proxy'leri ve yavaş parselleme hızı (dakikada 5-10 sayfa) gereklidir.
Uzun vadeli parselleme için IP rotasyonu ayarlama
IP adreslerinin doğru rotasyonu, tıbbi verilerin başarılı bir şekilde parselenmesi için anahtar bir faktördür. İki ana yaklaşım vardır: istek düzeyinde rotasyon ve zaman düzeyinde rotasyon.
İstek düzeyinde rotasyon
Bu yaklaşımda, her istek yeni bir IP adresi üzerinden gönderilir. Bu, yasaklanma riskini en aza indirir, ancak çerezler aracılığıyla oturumları izleyen sitelerde sorun yaratabilir. Oturum durumunu sürdürmenin gerekmediği liste ve katalog parselleme için uygundur.
Çoğu konut proxy sağlayıcısı, özel bir endpoint aracılığıyla otomatik rotasyon sunmaktadır. Örneğin, rotasyonlu proxy endpoint'i kullanıldığında, her yeni TCP bağlantısı yeni bir IP alır. Bu, Python'daki requests gibi kütüphanelerle otomatik olarak çalışır, çünkü varsayılan olarak her istek için yeni bir bağlantı oluşturulur.
Zaman düzeyinde rotasyon (sticky sessions)
Sticky sessions, belirli bir süre boyunca (genellikle 5-30 dakika) bir IP adresinin kullanılmasına izin verir, ardından otomatik olarak değişir. Bu, kimlik doğrulama gerektiren veya çerezler aracılığıyla oturum durumunu izleyen siteler için faydalıdır. Bir IP üzerinden birkaç sayfa parselleyebilir, gerçek bir kullanıcının davranışını taklit edebilir ve ardından IP otomatik olarak değişir.
Tıbbi siteler için, 10-15 dakika süresince sticky sessions kullanılması önerilir. Bu süre zarfında 10-20 sayfa parselleyebilirsiniz (gecikmelere bağlı olarak), ardından IP değişir ve "yeni bir oturum" başlarsınız. Bu, doğal görünür ve tespit riskini azaltır.
IP havuzunun boyutu
Uzun vadeli parselleme için, mevcut IP adreslerinin havuzunun boyutu önemlidir. Eğer bir hafta boyunca aynı 100 IP setini kullanıyorsanız, site bir kalıp fark edebilir ve tüm bu adresleri yasaklayabilir. Konut proxy'leri genellikle milyonlarca IP'ye erişim sağlar, bu da aynı adresin yeniden kullanılmasını neredeyse imkansız kılar.
Veri merkezi proxy'leri kullanırken, ortalama bir hacim için (ayda 10,000-50,000 sayfa) en az 500-1000 IP havuzuna sahip olmak önerilir. Büyük ölçekli parselleme (yüz binlerce sayfa) için, büyük IP havuzlarına sahip konut proxy'leri kullanmak daha iyidir.
Farklı kaynaklar için rotasyon önerisi:
- PubMed — rotasyon zorunlu değildir, rate limit'e uyularak 1 IP yeterlidir
- Ticari yayıncılar — 10-15 dakika sticky sessions, her 15-20 sayfada yeni IP
- İlaç veri tabanları — her istek için rotasyon veya 5 dakika sticky sessions
- Siteler Cloudflare ile — sticky sessions zorunludur, istek düzeyinde rotasyon çalışmaz
Proxy ile parselleme için Python'da kod örnekleri
Tıbbi verileri parsellemek için proxy ayarlarının pratik örneklerini inceleyelim. Temel bir örnekle başlayıp, yavaş yavaş karmaşıklaştıracağız.
Requests kütüphanesi ile temel ayar
import requests
from time import sleep
import random
# Proxy ayarları (verilerinizi değiştirin)
PROXY_HOST = "proxy.example.com"
PROXY_PORT = "8080"
PROXY_USER = "username"
PROXY_PASS = "password"
proxies = {
'http': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
'https': f'http://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}'
}
# Gerçek bir tarayıcıyı taklit etmek için başlıklar
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'DNT': '1',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'
}
# PubMed'e istek örneği
url = "https://pubmed.ncbi.nlm.nih.gov/?term=diabetes"
try:
response = requests.get(url, proxies=proxies, headers=headers, timeout=30)
print(f"Durum kodu: {response.status_code}")
print(f"İçerik uzunluğu: {len(response.content)}")
# İstekler arasında gecikme ekleyin (PubMed için zorunludur)
sleep(random.uniform(1.0, 3.0))
except requests.exceptions.RequestException as e:
print(f"Hata: {e}")
Rotasyon ve tekrar mantığı ile gelişmiş ayar
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from time import sleep
import random
class ProxyRotator:
def __init__(self, proxy_list):
"""
proxy_list: proxy'lerin sözlük listesi
[{'http': 'http://user:pass@host:port', 'https': '...'}, ...]
"""
self.proxy_list = proxy_list
self.current_index = 0
def get_next_proxy(self):
"""Listeden bir sonraki proxy'i al"""
proxy = self.proxy_list[self.current_index]
self.current_index = (self.current_index + 1) % len(self.proxy_list)
return proxy
def create_session_with_retries():
"""Hatalarda otomatik tekrarlarla bir oturum oluştur"""
session = requests.Session()
# Otomatik tekrar ayarları
retry_strategy = Retry(
total=3, # maksimum 3 deneme
backoff_factor=1, # denemeler arasındaki gecikme: 1, 2, 4 saniye
status_forcelist=[429, 500, 502, 503, 504], # tekrar için kodlar
allowed_methods=["GET", "POST"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)
return session
def scrape_with_rotation(urls, proxy_rotator):
"""Proxy rotasyonu ile URL listesini parselle"""
session = create_session_with_retries()
results = []
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.9',
}
for url in urls:
# Her istek için yeni bir proxy al
proxy = proxy_rotator.get_next_proxy()
try:
response = session.get(
url,
proxies=proxy,
headers=headers,
timeout=30
)
if response.status_code == 200:
results.append({
'url': url,
'status': 'başarılı',
'content_length': len(response.content)
})
print(f"✓ Başarılı: {url}")
else:
results.append({
'url': url,
'status': 'başarısız',
'error': f"Durum kodu: {response.status_code}"
})
print(f"✗ Başarısız: {url} (Durum: {response.status_code})")
except requests.exceptions.RequestException as e:
results.append({
'url': url,
'status': 'hata',
'error': str(e)
})
print(f"✗ Hata: {url} ({e})")
# İstekler arasında rastgele gecikme (önemli!)
sleep(random.uniform(2.0, 5.0))
return results
# Kullanım örneği
proxy_list = [
{
'http': 'http://user1:pass1@proxy1.example.com:8080',
'https': 'http://user1:pass1@proxy1.example.com:8080'
},
{
'http': 'http://user2:pass2@proxy2.example.com:8080',
'https': 'http://user2:pass2@proxy2.example.com:8080'
}
]
rotator = ProxyRotator(proxy_list)
urls_to_scrape = [
"https://pubmed.ncbi.nlm.nih.gov/?term=diabetes",
"https://pubmed.ncbi.nlm.nih.gov/?term=cancer",
"https://pubmed.ncbi.nlm.nih.gov/?term=covid"
]
results = scrape_with_rotation(urls_to_scrape, rotator)
JavaScript içeren siteler için Selenium kullanımı
Birçok modern tıbbi site, içeriği yüklemek için JavaScript kullanmaktadır. Bu durumlarda, headless tarayıcı gereklidir:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
def create_proxy_driver(proxy_host, proxy_port, proxy_user, proxy_pass):
"""Proxy ile Chrome WebDriver oluştur"""
chrome_options = Options()
# Headless mod (GUI olmadan)
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
# Proxy ayarı
chrome_options.add_argument(f'--proxy-server=http://{proxy_host}:{proxy_port}')
# Otomasyonu devre dışı bırakma (tespiti aşmak için önemlidir)
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
# User-Agent
chrome_options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')
driver = webdriver.Chrome(options=chrome_options)
# Kimlik doğrulama gerektiren proxy'ler için uzantı kullanmak gerekir
# veya capabilities aracılığıyla ayarlamak (daha karmaşık bir seçenek)
return driver
def scrape_with_selenium(url, driver):
"""JavaScript yüklemesini bekleyerek sayfayı parselle"""
driver.get(url)
# Elemanın yüklenmesini bekleme (örneğin, arama sonuçları)
try:
wait = WebDriverWait(driver, 10)
results = wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "results-article"))
)
# Verileri çıkarma
articles = driver.find_elements(By.CLASS_NAME, "results-article")
data = []
for article in articles:
try:
title = article.find_element(By.CLASS_NAME, "docsum-title").text
authors = article.find_element(By.CLASS_NAME, "docsum-authors").text
data.append({
'title': title,
'authors': authors
})
except:
continue
return data
except Exception as e:
print(f"Elemanları beklerken hata: {e}")
return []
# Kullanım örneği
proxy_host = "proxy.example.com"
proxy_port = "8080"
proxy_user = "username"
proxy_pass = "password"
driver = create_proxy_driver(proxy_host, proxy_port, proxy_user, proxy_pass)
try:
url = "https://pubmed.ncbi.nlm.nih.gov/?term=diabetes"
results = scrape_with_selenium(url, driver)
for result in results:
print(f"Başlık: {result['title']}")
print(f"Yazarlar: {result['authors']}\n")
finally:
driver.quit()
İstek hız kontrolü ve rate limiting aşma
Rate limiting, tıbbi sitelerin parsellemeye karşı uyguladığı ana koruma yöntemlerinden biridir. İstek hızının doğru bir şekilde ayarlanması, yasaklamalardan kaçınmak için kritik öneme sahiptir.
Güvenli hızın belirlenmesi
İlk adım, belirli bir sitenin limitlerini belirlemektir. Bu, istek hızını kademeli olarak artırarak 429 (Too Many Requests) hatası veya yasaklama oluşana kadar yapılabilir. Çoğu tıbbi site için güvenli değerler:
- PubMed — maksimum 3 istek/saniye (resmi öneri)
- ClinicalTrials.gov — dakikada 20 istek güvenlidir, 5 dakikada 100'e kadar kabul edilebilir
- Ticari yayıncılar — bir IP'den saatte 10-15 istek
- İlaç veri tabanları — dakikada 5-10 istek
Python'da rate limiter uygulaması
import time
from collections import deque
class RateLimiter:
def __init__(self, max_calls, period):
"""
max_calls: maksimum çağrı sayısı
period: saniye cinsinden zaman aralığı
Örneğin: RateLimiter(3, 1) = saniyede 3 istek
"""
self.max_calls = max_calls
self.period = period
self.calls = deque()
def __call__(self, func):
"""Fonksiyon çağrısını hız sınırlamak için dekoratör"""
def wrapper(*args, **kwargs):
now = time.time()
# Dönem dışındaki eski çağrıları kaldır
while self.calls and self.calls[0] < now - self.period:
self.calls.popleft()
# Limit aşılmışsa bekle
if len(self.calls) >= self.max_calls:
sleep_time = self.period - (now - self.calls[0])
if sleep_time > 0:
print(f"Hız limiti aşıldı, {sleep_time:.2f}s bekliyorum")
time.sleep(sleep_time)
# Beklemeden sonra temizle
self.calls.clear()
# Çağrı zamanını kaydet
self.calls.append(time.time())
# Fonksiyonu çalıştır
return func(*args, **kwargs)
return wrapper
# Kullanım örneği
@RateLimiter(max_calls=3, period=1) # saniyede 3 istek
def fetch_pubmed_page(url):
response = requests.get(url, headers=headers, proxies=proxies)
return response
# Artık fonksiyon otomatik olarak hız limitine uyar
for i in range(10):
result = fetch_pubmed_page(f"https://pubmed.ncbi.nlm.nih.gov/?term=test&page={i}")
print(f"Sayfa {i} alındı")
Adaptif hız sınırlama
Daha gelişmiş bir yaklaşım, sunucunun yanıtlarına bağlı olarak hızın adaptif olarak değiştirilmesidir. Eğer 429 veya 503 hataları alıyorsak, otomatik olarak hızı düşürmeliyiz:
import time
import random
class AdaptiveRateLimiter:
def __init__(self, initial_delay=1.0, max_delay=60.0):
self.current_delay = initial_delay
self.initial_delay = initial_delay
self.max_delay = max_delay
self.success_count = 0
def wait(self):
"""Sonraki isteğin öncesinde bekleme"""
# Doğallık için rastgelelik ekleyin
actual_delay = self.current_delay * random.uniform(0.8, 1.2)
time.sleep(actual_delay)
def on_success(self):
"""Başarılı bir istek alındığında çağrılır"""
self.success_count += 1
# 10 başarılı isteğin ardından biraz hızlanırız
if self.success_count >= 10:
self.current_delay = max(
self.initial_delay,
self.current_delay * 0.9
)
self.success_count = 0
def on_rate_limit(self):
"""429 veya benzeri hatalar alındığında çağrılır"""
# Gecikmeyi iki katına çıkarırız, ama maksimuma ulaşmadan
self.current_delay = min(
self.current_delay * 2,
self.max_delay
)
self.success_count = 0
print(f"Hız limiti aşıldı! Gecikmeyi {self.current_delay:.2f}s olarak artırıyorum")
def on_error(self):
"""Diğer hatalar alındığında çağrılır"""
# Gecikmeyi biraz artırırız
self.current_delay = min(
self.current_delay * 1.5,
self.max_delay
)
self.success_count = 0
# Kullanım örneği
limiter = AdaptiveRateLimiter(initial_delay=2.0, max_delay=30.0)
for url in urls_to_scrape:
limiter.wait()
try:
response = requests.get(url, proxies=proxies, headers=headers)
if response.status_code == 200:
limiter.on_success()
# Verileri işleyin
elif response.status_code == 429:
limiter.on_rate_limit()
# Daha sonra tekrar deneyin
else:
limiter.on_error()
except requests.exceptions.RequestException:
limiter.on_error()
Tıbbi siteler için doğru başlıklar ve User-Agent
Tıbbi siteler, bot tespiti için HTTP başlıklarını analiz etmektedir. Yanlış veya eksik başlıklar, kaliteli proxy kullanılsa bile yasaklamaların yaygın bir nedenidir.
Zorunlu başlıklar
Her istekte bulunması gereken minimum başlık seti:
headers = {
# User-Agent — güncel bir tarayıcı zorunludur
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
# Accept — tarayıcının kabul ettiği içerik türleri
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
# Accept-Language — kullanıcının dili
'Accept-Language': 'en-US,en;q=0.9',
# Accept-Encoding — sıkıştırma desteği
'Accept-Encoding': 'gzip, deflate, br',
# Connection — bağlantının sürdürülmesi
'Connection': 'keep-alive',
# Upgrade-Insecure-Requests — otomatik HTTPS geçişi
'Upgrade-Insecure-Requests': '1',
# DNT — Do Not Track (isteğe bağlı, ama gerçekçilik katar)
'DNT': '1',
# Sec-Fetch-* başlıkları (modern tarayıcılar için önemlidir)
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-User': '?1',
# Cache-Control
'Cache-Control': 'max-age=0'
}
User-Agent rotasyonu
Aynı User-Agent kullanmak şüpheli olabilir. Birkaç güncel tarayıcı arasında rotasyon yapılması önerilmektedir:
import random
USER_AGENTS = [
# Windows'ta Chrome
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
# Mac'te Chrome
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
# Windows'ta Firefox
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
# Mac'te Firefox
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0',
# Mac'te Safari
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15',
# Windows'ta Edge
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0'
]
def get_random_headers():
"""Rastgele User-Agent ile başlıkları al"""
return {
'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',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
'DNT': '1'
}
# Kullanım
for url in urls:
headers = get_random_headers()
response = requests.get(url, headers=headers, proxies=proxies)
Formlar için Referer ve Origin
Arama formları ile çalışırken veya POST istekleri gönderirken, Referer ve Origin başlıklarını eklemek zorunludur:
# Arama formuna POST isteği için
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/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',
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': 'https://example.com',
'Referer': 'https://example.com/search',
'Connection': 'keep-alive'
}
# Form verileri ile POST isteği
data = {
'query': 'diabetes',
'page': '1'
}
response = requests.post(
'https://example.com/search',
headers=headers,
data=data,
proxies=proxies
)
Tipik sorunlar ve çözümleri
Tıbbi verileri parselleme sırasında belirli sorunlar ortaya çıkabilir. En yaygın olanları ve çözümlerini inceleyelim.
Sorun: Cloudflare tüm istekleri engelliyor
Belirtiler: "Tarayıcınızı kontrol ediyor" yazılı sayfa veya Cloudflare ile ilgili 403 Forbidden hatası alıyorsunuz.
Çözüm:
- Veri merkezi yerine konut proxy'leri kullanın — Cloudflare, veri merkezi IP'lerini varsayılan olarak engeller
- Selenium veya Puppeteer'e geçin — headless tarayıcılar Cloudflare kontrollerinden daha iyi geçer
- Python için cloudscraper kütüphanesini kullanın — temel Cloudflare korumasını otomatik olarak aşar
- Çerezleri ve JavaScript'i etkinleştirin — Cloudflare bunların varlığını kontrol eder
- TLS fingerprinting ekleyin — gerçek bir tarayıcıyı TLS düzeyinde taklit etmek için curl_cffi kullanın
Sorun: 429 Too Many Requests hatası alıyorum
Belirtiler: Birkaç başarılı isteğin ardından sunucu 429 döndürmeye başlıyor.
Çözüm:
- İstekler arasındaki gecikmeyi artırın — 3-5 saniye ile başlamayı deneyin
- IP rotasyonunu etkinleştirin — her istek yeni bir IP üzerinden yapılırsa rate limiting kaldırılır
- 429 yanıtındaki Retry-After başlığını kontrol edin — beklemeniz gereken süreyi belirtir
- Tekrarlar için üstel gecikme kullanın — 1s, 2s, 4s, 8s vb.
Sorun: Proxy'ler yavaş çalışıyor veya sık sık kopuyor
Belirtiler: Zaman aşımı hataları, sayfaların çok uzun sürede yüklenmesi, bağlantı kopmaları.
Çözüm:
- İsteklerdeki zaman aşımını 30-60 saniyeye çıkarın — konut proxy'leri daha yavaş olabilir
- Coğrafi olarak yakın proxy'ler kullanın — Avrupa sitesini parselliyorsanız, Avrupa IP'leri kullanın
- Proxy sağlayıcısının kalitesini kontrol edin — ucuz proxy'ler genellikle kararsızdır
- Tekrar mantığı ekleyin — bağlantı hatası durumunda isteği otomatik olarak tekrar edin
- Bağlantı havuzlaması kullanın — requests.Session() aracılığıyla TCP bağlantılarını yeniden kullanın
Sorun: Site kimlik doğrulama veya abonelik istiyor
Belirtiler: Makalelerin tam metnine erişim kısıtlı, giriş yapılması gerekiyor.
Çözüm:
- Kurumsal erişim kullanın — birçok üniversite ve hastane aboneliklere sahiptir
- Açık Erişim versiyonlarının mevcut olup olmadığını kontrol edin — birçok makale, arşivler aracılığıyla ücretsiz olarak erişilebilir
- Parselleme yerine API kullanın — bazı yayıncılar araştırmacılara API sunmaktadır
- Sadece meta verileri (başlıklar, yazarlar, özetler) parselleyin — bunlar genellikle ücretsiz olarak erişilebilir
Sorun: JavaScript içeriği yüklenmiyor
Belirtiler: HTML'de gerekli veriler yok, sadece yüklenme dönerleri veya boş konteynerler görünmekte.
Çözüm:
- Selenium/Puppeteer'e geçin — bunlar JavaScript'i çalıştırır
- API uç noktasını bulun — tarayıcıda DevTools'u açın, Network sekmesi, ve verilerle XHR isteklerini bulun
- requests-html kullanın — JavaScript içeriğini yüklemek için bir kütüphane