Google Akademik'te art arda 40-50 sorgu gönderdiğinizde ya da PubMed'de aynı IP'den tekrarlayan aramalar yaptığınızda karşınıza bir CAPTCHA çıkar — bu, akademik veritabanlarının otomasyonu sınırlamak için kullandığı standart savunma. Literatür taraması, bibliyometrik analiz veya meta-çalışma için yüzlerce makaleyi taramanız gerektiğinde bu doğrulamalar script'inizi durdurur. Çözüm basit: sitekey'i sayfadan çıkarın, CaptchaAI API'sine gönderin, dönen token'ı forma enjekte edin ve taramaya kaldığınız yerden devam edin. Aşağıda Google Akademik, PubMed, Web of Science, Scopus, IEEE Xplore ve JSTOR için çalışan bir Python akışı var.
Hangi Akademik Kaynaklar CAPTCHA ile Karşınıza Çıkar?
| Kaynak | CAPTCHA Türü | Tetikleyici | Veri |
|---|---|---|---|
| Google Akademik | reCAPTCHA v3 | Yüksek hacimli sorgular | Atıflar, makaleler |
| PubMed | reCAPTCHA v2 | Tekrarlanan aramalar | Biyomedikal literatür |
| Web of Science | Cloudflare Turnstile | Toplu indirmeler | Atıf metrikleri |
| Scopus | reCAPTCHA v2 | Dışa aktarma işlemleri | Bibliyometrik veriler |
| IEEE Xplore | reCAPTCHA v2 | Arama + indirme | Mühendislik belgeleri |
| JSTOR | reCAPTCHA v2 | Sayfa erişimi | Beşeri bilimler / sosyal bilimler |
Altısı da aynı deseni izler: sitekey'i HTML'den çeker, CaptchaAI'ye gönderir, dönen token'ı g-recaptcha-response veya cf-turnstile-response alanına yazarsınız. Değişen tek şey hangi CAPTCHA türünün tetiklendiği ve ne sıklıkla tekrarlandığıdır.
Akademik Sitelerde İstek Sınırlaması
CAPTCHA'yı çözmek işin yarısı; diğer yarısı akademik sitenin IP'nizi hiç işaretlememesi. Devlet üniversitesi ağlarından veya paylaşılan kurumsal IP'lerden çalışan script'ler özellikle risklidir — aynı çıkış IP'sini onlarca araştırmacı paylaşıyor olabilir. Aşağıdaki değerler gözlemlenen verilere dayanır; ortama, saat dilimine ve hacme göre değişebilir.
| Kaynak | Önerilen Gecikme | Saatte Maksimum Sayfa |
|---|---|---|
| Google Akademik | 10-15 saniye | 40-50 |
| PubMed | 3-5 saniye | 100 |
| Web of Science | 5-10 saniye | 60 |
| Scopus | 5-10 saniye | 60 |
| IEEE | 3-5 saniye | 100 |
| JSTOR | 5-10 saniye | 60 |
Örneğin İstanbul saatiyle (Europe/Istanbul) gece 02:00-06:00 arasında çalıştırılan bir toplu iş, gündüz saatlerine göre genelde daha az CAPTCHA'yla karşılaşır — akademik sitelerin en yoğun trafik pencereleri iş saatlerine denk gelir. Akademik siteler IP'leri hızlı biçimde işaretler; muhafazakâr gecikmelerle başlayıp hata oranınıza göre daraltın.
Python ile Atıf Verisi Toplama
Aşağıdaki script iki parçadan oluşur: CaptchaAI'ye görev gönderip token'ı bekleyen solve_captcha fonksiyonu ve arama sonuçlarını sayfalayarak gezen AcademicScraper sınıfı. _has_captcha metodu sayfada data-sitekey, g-recaptcha veya cf-turnstile işaretlerinden birini bulduğunda akış otomatik olarak token çözümüne düşer.
import requests
import time
import re
from bs4 import BeautifulSoup
import csv
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("Timeout")
class AcademicScraper:
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_papers(self, search_url, query, max_pages=10):
"""Search academic database for papers matching query."""
all_papers = []
for page in range(max_pages):
url = f"{search_url}?q={query}&start={page * 10}"
resp = self.session.get(url, timeout=30)
# Handle CAPTCHA
if self._has_captcha(resp.text):
resp = self._solve_and_retry(resp.text, url)
papers = self._parse_results(resp.text)
if not papers:
break # No more results
all_papers.extend(papers)
print(f"Page {page + 1}: {len(papers)} papers")
time.sleep(5) # Respectful delay
return all_papers
def get_paper_details(self, paper_url):
"""Get detailed metadata for a single paper."""
resp = self.session.get(paper_url, timeout=30)
if self._has_captcha(resp.text):
resp = self._solve_and_retry(resp.text, paper_url)
soup = BeautifulSoup(resp.text, "html.parser")
return {
"title": self._safe_text(soup, "h1, .article-title"),
"authors": self._safe_text(soup, ".authors, .author-list"),
"abstract": self._safe_text(soup, ".abstract, #abstract"),
"doi": self._safe_text(soup, ".doi, [data-doi]"),
"journal": self._safe_text(soup, ".journal-name, .publication"),
"year": self._safe_text(soup, ".pub-date, .year"),
"citations": self._safe_text(soup, ".citation-count, .cited-by"),
}
def export_to_csv(self, papers, filename):
"""Export collected papers to CSV."""
if not papers:
return
keys = papers[0].keys()
with open(filename, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=keys)
writer.writeheader()
writer.writerows(papers)
print(f"Exported {len(papers)} papers to {filename}")
def _has_captcha(self, html):
return any(tag in html.lower() for tag in [
'data-sitekey', 'g-recaptcha', 'cf-turnstile',
])
def _solve_and_retry(self, html, url):
match = re.search(r'data-sitekey="([^"]+)"', html)
if not match:
return self.session.get(url)
sitekey = match.group(1)
if 'cf-turnstile' in html:
token = solve_captcha("turnstile", sitekey, url)
return self.session.post(url, data={"cf-turnstile-response": token})
else:
token = solve_captcha("userrecaptcha", sitekey, url)
return self.session.post(url, data={"g-recaptcha-response": token})
def _parse_results(self, html):
soup = BeautifulSoup(html, "html.parser")
papers = []
for item in soup.select(".gs_r, .search-result, article.result"):
title_el = item.select_one("h3 a, .result-title a")
if title_el:
papers.append({
"title": title_el.get_text(strip=True),
"url": title_el.get("href", ""),
"snippet": self._safe_text(item, ".gs_rs, .abstract-snippet"),
"authors": self._safe_text(item, ".gs_a, .author-info"),
})
return papers
def _safe_text(self, soup, selector):
el = soup.select_one(selector)
return el.get_text(strip=True) if el else ""
# Usage — Literature review
scraper = AcademicScraper(
proxy="http://user:pass@residential.proxy.com:5000"
)
papers = scraper.search_papers(
"https://scholar.example.com/scholar",
query="machine learning CAPTCHA solving",
max_pages=5,
)
# Get details for top papers
detailed = []
for paper in papers[:20]:
if paper["url"]:
detail = scraper.get_paper_details(paper["url"])
detailed.append(detail)
time.sleep(3)
scraper.export_to_csv(detailed, "literature_review.csv")
Atıf Ağı Taraması (Bibliyometrik Analiz)
Tek bir makaleyi değil, ona atıf yapan makaleleri de takip etmek isterseniz aynı AcademicScraper nesnesini özyinelemeli bir tarama fonksiyonuna besleyin. depth parametresi kaç seviye derine ineceğinizi, her seviyedeki citations[:5] sınırı ise genişliği kontrol eder — sınırsız bırakırsanız atıf ağı birkaç seviyede binlerce makaleye çıkabilir.
def bibliometric_analysis(scraper, seed_papers, depth=2):
"""Follow citations to build a citation network."""
visited = set()
network = []
def _crawl(paper_url, current_depth):
if current_depth > depth or paper_url in visited:
return
visited.add(paper_url)
try:
details = scraper.get_paper_details(paper_url)
network.append(details)
# Follow "cited by" links
resp = scraper.session.get(f"{paper_url}/citations", timeout=30)
if scraper._has_captcha(resp.text):
resp = scraper._solve_and_retry(resp.text, f"{paper_url}/citations")
citations = scraper._parse_results(resp.text)
for cite in citations[:5]: # Limit breadth
if cite["url"]:
_crawl(cite["url"], current_depth + 1)
time.sleep(3)
except Exception as e:
print(f"Error crawling {paper_url}: {e}")
for paper in seed_papers:
_crawl(paper["url"], 0)
return network
Sık Karşılaşılan Sorunlar ve Çözümleri
Akademik scraping'de en sık karşılaşılan beş sorun ve pratik çözümleri:
| Sorun | Sebep | Çözüm |
|---|---|---|
| Her aramada CAPTCHA çıkıyor | Akademik site IP'nizi işaretlemiş | Proxy yapılandırmanızı değiştirin, gecikmeyi 15+ saniyeye çıkarın |
| Hiç sonuç dönmüyor | Ayrıştırdığınız aslında bir CAPTCHA sayfası | Ayrıştırmadan önce _has_captcha ile kontrol edin |
| Özet (abstract) eksik geliyor | İçerik ödeme duvarının (paywall) arkasında | Kurumsal proxy veya açık erişim (open access) kaynağı kullanın |
| Google Akademik IP'nizi engelliyor | Saatlik istek sınırı aşıldı | 30 dakika bekleyin, farklı bir IP'ye geçin |
| Dışa aktarma sınırlı kalıyor | Site toplu indirmeyi kısıtlıyor | Daha küçük gruplar halinde indirin |
KVKK ve yazar verileri
Makale meta verisi (başlık, özet, DOI, atıf sayısı) genelde herkese açıktır ve toplanması başlı başına sorun yaratmaz. Ancak yazar e-postası veya kurum bilgisi gibi kişisel veriler de topluyorsanız, bu veriler KVKK (Kişisel Verilerin Korunması Kanunu) kapsamına girer. Toplama işlemini yetkilendirilmiş araştırma amaçlarıyla sınırlı tutun, veriyi gereğinden uzun süre saklamayın ve mümkün olan yerde PubMed E-utilities gibi resmi API'leri tercih edin.
SSS
Google Akademik'te CAPTCHA neden bu kadar sık çıkıyor?
Google Akademik reCAPTCHA v3 kullanır; bu sistem arka planda bir risk skoru hesaplar ve şüpheli görülen isteklere doğrulama sorar. Kısa aralıklarla gönderilen çok sayıda sorgu, sabit bir user-agent veya veri merkezi kaynaklı IP trafiği skoru düşürür ve CAPTCHA'yı daha sık tetikler.
PubMed'de CAPTCHA'yla hiç karşılaşmamak mümkün mü?
Büyük ölçüde evet. PubMed'in E-utilities API'si programatik erişimi resmi olarak destekler ve CAPTCHA'ya takılmadan arama/indirme yapmanızı sağlar. CaptchaAI'yi yalnızca tarayıcı tabanlı erişim zorunlu olduğunda ya da E-utilities'in kapsamadığı sayfalarda devreye almanız yeterli.
Taranan yazar ve e-posta verileri KVKK kapsamına girer mi?
Evet, kişisel veri niteliğindeki yazar iletişim bilgileri KVKK'ya tabidir. Başlık, özet ve atıf sayısı gibi anonim bibliyometrik veriler bu kapsamın dışındadır; e-posta veya kurum bilgisi topluyorsanız veriyi yalnızca yetkilendirilmiş araştırma amacıyla ve sınırlı süreyle saklayın.
CaptchaAI'yi üniversite veya kurum proxy'siyle birlikte kullanabilir miyim?
Evet. Tarama oturumu için kurumunuzun proxy yapılandırmasını, CAPTCHA çözümü için CaptchaAI API'sini ayrı ayrı kullanırsınız — ikisi birbirinden bağımsız çalışır ve aynı istek akışında birlikte kullanılabilir.
Saatte kaç sorgu göndermek güvenli sayılır?
Kaynağa göre değişir: PubMed ve IEEE'de saatte 100 sayfaya kadar genelde sorun çıkmazken, Google Akademik'te 40-50 sayfanın üstüne çıkmak hızla CAPTCHA'ya ve IP engeline yol açar. Yukarıdaki gecikme tablosunu başlangıç noktası olarak alın ve gözlemlediğiniz hata oranına göre ayarlayın.
İlgili Kılavuzlar
Literatür taramanızı hızlandırın — CaptchaAI anahtarınızı alın ve akademik veri toplamayı otomatikleştirin.