Web Kazıma: JavaScript mi Python mu?

Yayın tarihi:

9 dk okuma

Acar Diveroli
Yazar: Acar Diveroli
Python ve JavaScript karşılaştırması: komut istemi ve süslü parantez simgeleri

Web kazıma projesine başlayan hemen herkes aynı soruyla karşılaşır: Python mı, JavaScript mi? İki dil de bu işi rahatlıkla yapar ve iki tarafta da olgun araçlar var. Doğru seçim; hedef sitelerin yapısına, verinin sonrasında ne olacağına ve ekibinizin zaten hangi dili bildiğine bağlıdır.

Bu yazıda iki dili aynı görev üzerinden karşılaştırıyor, araç ekosistemlerini, dinamik sayfalarda ve ölçekte nasıl davrandıklarını, dağıtım ve bakım yükünü ele alıyor ve kararınızı kolaylaştıracak bir rehber sunuyoruz.

Aynı görev, iki dil

Görev basit: Bir sayfanın HTML'ini proxy üzerinden çekip başlığını okumak. Aşağıdaki iki örnek de aynı işi yapar.

Python: Requests ve Beautiful Soup

bash
pip install requests beautifulsoup4
python
import requests
from bs4 import BeautifulSoup

PROXY = "http://kullanici:parola@pr.proxynet.io:8000"

html = requests.get(
    "https://example.com",
    proxies={"http": PROXY, "https": PROXY},
    timeout=20,
).text

soup = BeautifulSoup(html, "html.parser")
print(soup.select_one("h1").get_text(strip=True))

JavaScript (Node.js): fetch ve Cheerio

bash
npm install undici cheerio
javascript
import { fetch, ProxyAgent } from "undici";
import * as cheerio from "cheerio";

const dispatcher = new ProxyAgent("http://kullanici:parola@pr.proxynet.io:8000");

const html = await (await fetch("https://example.com", { dispatcher })).text();
const $ = cheerio.load(html);
console.log($("h1").first().text().trim());

Görüldüğü gibi statik bir sayfa için iki dil de neredeyse aynı uzunlukta ve aynı mantıkla çalışır. Seçici sözdizimi bile aynıdır: Beautiful Soup'un select_one ve Cheerio'nun $() çağrısı CSS seçicileri kabul eder. Asıl farklar işin boyutu büyüdükçe ortaya çıkar.

Araç ekosistemleri yan yana

GörevPythonJavaScript (Node.js)
HTTP istemcisiRequests, HTTPX, AIOHTTPfetch (undici), Axios
HTML ayrıştırmaBeautiful Soup, lxml, parselCheerio, jsdom
Tarayıcı otomasyonuPlaywright, SeleniumPuppeteer, Playwright
Kazıma çatısıScrapyCrawlee
Veri işlemepandas, NumPy, polarsSınırlı; genelde veri tabanına yazılır
Zamanlama ve kuyrukCelery, APSchedulerBullMQ, node-cron
Dışa aktarmaCSV, Parquet, Excel doğrudanCSV, JSON; Parquet için ek paket

İki sütun da eksiksizdir; fark, hangi halkanın daha güçlü olduğundadır. Python'da veri işleme halkası, JavaScript'te tarayıcı halkası öne çıkar.

Python'un güçlü olduğu yerler

  • Veri işleme ekosistemi. Toplanan veriyi temizlemek, analiz etmek ve dışa aktarmak için pandas, NumPy ve benzeri kütüphaneler çok olgundur. Kazıma işinin çıktısı bir analiz veya makine öğrenmesi hattına gidiyorsa Python doğal bir seçimdir; aynı dilde kalırsınız.
  • Hazır kazıma çatısı. Scrapy; istek kuyruğu, yeniden deneme, hız sınırlama, veri dışa aktarma ve ara katman (middleware) mimarisini tek pakette sunar. Büyük ve tekrarlanan tarama işleri için sağlam bir iskelet sağlar; proxy rotasyonu bir ara katmanla eklenir.
  • HTTP istemcisi seçenekleri. Basit işler için Requests, yüksek eşzamanlılık için HTTPX veya AIOHTTP bulunur. Aralarındaki farkları HTTPX, Requests ve AIOHTTP karşılaştırmamızda anlattık.
  • Öğrenme kolaylığı. Programlamaya yeni başlayan biri için Python'un sözdizimi genellikle daha anlaşılırdır; asenkron yapı zorunlu değildir, gerektiğinde eklenir.
  • Veri bilimi ekipleriyle uyum. Analist ve veri bilimci ekipler çoğunlukla Python bilir; kazıma kodunun onların okuyup değiştirebileceği dilde olması bakım yükünü azaltır.

JavaScript'in güçlü olduğu yerler

  • Dinamik sayfalar. İçeriği tarayıcıda JavaScript ile yüklenen sitelerde tarayıcıyı yöneten araçlar gerekir. Puppeteer ve Playwright bu alanın öncüleridir ve Node.js ekosisteminde doğmuşlardır. Sayfanın içinde çalışan kodla aynı dili konuşmak, page.evaluate içinde yazdığınız kodun betiğin geri kalanıyla aynı dil olması demektir; hata ayıklama kolaylaşır.
  • Doğal eşzamanlılık. Node.js baştan olay döngüsü üzerine kurulmuştur; çok sayıda isteği aynı anda beklemek dilin varsayılan çalışma biçimidir. Python'da bunun için asyncio ve uyumlu kütüphaneler gerekir.
  • Tarayıcı araçlarıyla aynı dil. Geliştirici konsolunda denediğiniz bir seçiciyi veya kodu doğrudan betiğe taşıyabilirsiniz.
  • Tam yığın ekipler. Ekibiniz zaten web uygulamasını JavaScript veya TypeScript ile yazıyorsa, kazıma kodunu aynı dilde tutmak bakım yükünü azaltır ve tür tanımlarını paylaşmanızı sağlar.
  • Crawlee gibi modern çatılar. HTTP ve tarayıcı tabanlı tarayıcıları tek arayüzde birleştiren, oturum ve proxy yönetimini yerleşik sunan çatılar Node.js tarafında olgunlaşmıştır.

Karşılaştırma tablosu

ÖlçütPythonJavaScript (Node.js)
Statik sayfa kazımaRequests + Beautiful Soupfetch + Cheerio
Dinamik sayfa (tarayıcı)Selenium, PlaywrightPuppeteer, Playwright
Kazıma çatısıScrapyCrawlee
Eşzamanlılıkasyncio ileDilin varsayılanı
Veri analiziÇok güçlüSınırlı
Tür güvenliğiİsteğe bağlı (type hints)TypeScript ile güçlü
Öğrenme eğrisiKolayOrta (asenkron yapı nedeniyle)
DağıtımSanal ortam, konteynernpm, konteyner; sunucusuz ortamlarda yaygın
En uygun projeVeri odaklı, analiz hattına bağlıTarayıcı odaklı, dinamik içerik

Dinamik içerik: asıl ayrım noktası

Seçimi çoğu zaman dil değil, hedef sayfanın nasıl yüklendiği belirler. Sayfanın kaynağında (tarayıcıda "Sayfa kaynağını görüntüle") aradığınız veri varsa basit bir HTTP isteği yeterlidir ve her iki dil de işinizi hızla görür.

Veri, sayfa açıldıktan sonra JavaScript ile yükleniyorsa iki seçenek vardır:

  1. Arka plandaki API isteğini bulmak. Tarayıcının geliştirici araçlarındaki Ağ sekmesinde sayfanın veriyi hangi adresten çektiğine bakın. Çoğu zaman bu adres doğrudan JSON döndürür ve tarayıcıya hiç ihtiyacınız kalmaz. Bu yöntem hem daha hızlı hem daha az kaynak tüketir; iki dilde de aynı kolaylıkta yapılır.
  2. Gerçek bir tarayıcı çalıştırmak. API bulunamıyorsa veya karmaşık etkileşim gerekiyorsa Playwright (iki dilde de var), Puppeteer (JavaScript) ya da Selenium (Python) kullanılır.

Tarayıcı otomasyonunun kendi zorlukları vardır: Her sayfa için gerçek bir tarayıcı çalışır, bellek ve işlemci tüketimi HTTP isteğinin katbekat üstündedir ve bot korumaları tarayıcı izlerine bakar. CAPTCHA'nın neden tetiklendiğini Puppeteer ve CAPTCHA, Python tarafındaki araçları ise Selenium ve Undetected ChromeDriver yazılarımızda ele aldık.

Aynı görev, tarayıcıyla

Dinamik bir sayfada aynı başlığı okumak için iki dilde de Playwright kullanılabilir; sözdizimi neredeyse birebirdir.

Python:

python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(proxy={
        "server": "http://pr.proxynet.io:8000",
        "username": "kullanici",
        "password": "parola",
    })
    page = browser.new_page()
    page.goto("https://example.com")
    print(page.locator("h1").first.inner_text())
    browser.close()

JavaScript:

javascript
import { chromium } from "playwright";

const browser = await chromium.launch({
  proxy: { server: "http://pr.proxynet.io:8000", username: "kullanici", password: "parola" },
});
const page = await browser.newPage();
await page.goto("https://example.com");
console.log(await page.locator("h1").first().innerText());
await browser.close();

Playwright'ın iki dilde de aynı API'yi sunması, dil kararının tarayıcı otomasyonu yüzünden verilmesini gereksiz kılar. Fark, tarayıcıdan çıkan verinin sonrasında nereye gittiğindedir.

Ölçekte ne değişir?

Yüz sayfalık bir işte dil farkı hissedilmez. Yüz bin sayfada üç konu öne çıkar:

  • Eşzamanlılık yönetimi. Node.js'te doğal, Python'da asyncio ile. İki tarafta da eşzamanlılığı sınırlamak (semafor, kuyruk) gerekir; sınırsız eşzamanlılık hedef siteyi ve kendi bağlantı sınırlarınızı zorlar.
  • Bellek. Tarayıcı tabanlı kazımada bellek tüketimi dilden değil tarayıcıdan gelir. HTTP tabanlı kazımada iki dil de hafiftir.
  • Hata ve yeniden deneme. Ağ hataları, 429 yanıtları ve proxy hataları için üstel bekleme ile yeniden deneme iki dilde de elle ya da çatı aracılığıyla yazılır. Scrapy ve Crawlee bunu yerleşik sunar.

Ölçekte belirleyici olan dördüncü konu ise dille hiç ilgili değildir: erişim.

Dilden bağımsız olan kısım: erişim

Hangi dili seçerseniz seçin, ölçek büyüdüğünde karşılaşacağınız sorunlar aynıdır: IP engelleri, hız sınırları ve konuma göre değişen içerik. Bu sorunlar kodun değil, trafiğin nereden ve nasıl geldiğinin sonucudur.

  • Çok sayıda bağımsız sayfa çekiyorsanız Rotating Proxy her istekte farklı bir IP kullanarak yükü dağıtır.
  • Korumalı hedeflerde gerçek kullanıcı adreslerinden gelen Residential Proxy daha az engelle karşılaşır; nedenini Residential ve Datacenter Proxy Farkı yazımızda anlattık.
  • Giriş yapılan ya da çok adımlı akışlarda Sticky Proxy aynı IP'yi oturum boyunca korur.
  • Farklı ülkelerdeki fiyatları veya arama sonuçlarını karşılaştırıyorsanız konum hedeflemeli IP'ler gerekir; ayrıntılar SEO ve SERP takibi ve fiyat takibi sayfalarımızda.

Sayfanın içeriğini anlamak için yapay zeka modellerinden yararlanmak da iki dilde mümkündür; bunun kazıma akışındaki yerini GPT-6 Astra ile Web Kazıma yazımızda tartıştık. Hangi verinin hangi koşullarda toplanabileceği de dilden bağımsızdır; Web Scraping Yasal mı? yazımızda ele aldık.

Hangisini seçmelisiniz?

  • Python'u seçin: Veri analizi, raporlama veya makine öğrenmesi hattına veri topluyorsanız; büyük ve düzenli tarama işleri için Scrapy gibi bir çatı istiyorsanız; ekibiniz Python biliyorsa.
  • JavaScript'i seçin: Hedefleriniz ağırlıklı olarak dinamik, tarayıcı gerektiren sitelerse; ekibiniz zaten Node.js veya TypeScript ile çalışıyorsa; kazıma kodu bir web uygulamasının parçası olacaksa.

Kararsız kaldığınızda ekibinizin en çok kullandığı dille başlayın. İki dilin araçları da yeterince olgundur; projeyi başarıya taşıyan şey genellikle dil değil, doğru erişim stratejisi ve sağlam hata yönetimidir.

Karar rehberi

DurumÖneri
Çıktı pandas ile analiz edilecekPython
Çıktı bir Node.js uygulamasına akacakJavaScript
Hedeflerin çoğu statik HTMLİkisi de; ekibin bildiği dil
Hedeflerin çoğu tarayıcı gerektiriyorJavaScript (Puppeteer) veya Playwright ile ikisi de
Büyük, düzenli, çok siteli taramaPython (Scrapy) veya JavaScript (Crawlee)
Ekipte veri bilimci varPython
Ekipte tam yığın web geliştiricisi varJavaScript
Sunucusuz ortamda kısa görevlerJavaScript

Sık sorulan sorular

Performans açısından hangisi daha hızlı?

Kazımada zamanın büyük bölümü ağda, yani sunucunun yanıtını beklerken geçer. Her iki dilde de asenkron istemciler kullanıldığında fark belirleyici olmaz. Sayfa ayrıştırma hızı ise çoğu projede darboğaz değildir.

Playwright hangi dille daha iyi?

Playwright; JavaScript/TypeScript, Python, Java ve .NET için resmi olarak desteklenir. Yeni özellikler genellikle önce Node.js sürümüne gelir, ancak Python sürümü de günlük kazıma işleri için eksiksizdir.

İki dili aynı projede kullanabilir miyim?

Evet. Örneğin dinamik sayfaları Node.js ile tarayıp ham veriyi bir kuyruğa yazabilir, analiz ve temizleme işini Python tarafında yapabilirsiniz. Kuyruk ya da veri tabanı, iki dünyayı bağlayan doğal arayüzdür.

Scrapy ile Crawlee arasındaki fark ne?

İkisi de tam bir kazıma çatısıdır. Scrapy HTTP tabanlıdır ve tarayıcı için eklenti gerektirir; Crawlee HTTP ve tarayıcı tabanlı tarayıcıları aynı arayüzde sunar. Scrapy daha uzun süredir var ve ekosistemi geniştir; Crawlee TypeScript desteği ve yerleşik oturum yönetimiyle öne çıkar.

Kazıma için TypeScript kullanmalı mıyım?

Ekibiniz TypeScript biliyorsa evet; ayrıştırılan verinin şemasını tür olarak tanımlamak, alan adı değişikliklerini derleme zamanında yakalar. Küçük betiklerde düz JavaScript yeterlidir.

Proxy kullanımı dile göre değişir mi?

Mantık aynıdır: HTTP istemcisine ya da tarayıcıya proxy adresi ve kimlik bilgileri verilir. Sözdizimi kütüphaneye göre değişir; Python örnekleri için Python'da Proxy'ler Nasıl Döndürülür?, Node.js için JavaScript'te cURL yazımıza bakabilirsiniz.

Özetle

Python, toplanan verinin işlenmesi ve büyük tarama çatıları söz konusu olduğunda; JavaScript ise dinamik sayfalar ve tarayıcı otomasyonunda öne çıkar. Statik sayfalarda iki dil de eşit derecede iyidir ve Playwright sayesinde tarayıcı otomasyonu da dil kararını belirlemez. Seçim ne olursa olsun ölçek büyüdükçe belirleyici olan erişim altyapısıdır. Büyük ölçekli projeler için veri kazıma çözümlerimize göz atabilirsiniz.

ChatGPT'ye sorClaude'a sor