Screaming Frog, çoğu SEO için tercih edilen tarayıcıdır, ancak muhtemelen sınırlarına tosladınız: ücretsiz sürümde 500 URL sınırı, büyük sitelerde RAM’in tükenmesi veya bir GUI’yi izlemeden taramaları otomatikleştirme isteği. Scrapy, bu sınırları kaldıran açık kaynaklı Python çerçevesidir.

npm install veya git clone çalıştırabiliyorsanız, Scrapy’yi çalıştırabilirsiniz. Öğrenme eğrisi gerçek ama yönetilebilir, özellikle ajantik kodlama iş akışları aracılığıyla CLI araçlarıyla zaten rahat hissediyorsanız.

Neden Scrapy?

Temel Faydalar

Screaming Frog hızlı denetimler için harika çalışır. Ama sınırları var:

Sınırlama Etki
500 URL ücretsiz limiti Daha büyük siteler için yılda 259$ lisans gerektirir
Bellek aç Büyük taramalar 8GB+ RAM tüketebilir
GUI bağımlı Otomatikleştirmek veya zamanlamak zor
Sınırlı özelleştirme Yapılandırma seçenekleri sabit

Scrapy bunları çözer:

Scrapy Ne elde edersiniz
Ücretsiz ve açık kaynak URL limiti yok, lisans ücreti yok
Daha düşük bellek ayak izi Disk destekli kuyruklar RAM’i kontrol altında tutar
CLI-yerel Scriptlenebilir, cron’lanabilir, CI/CD’ye hazır
Tam Python özelleştirmesi İhtiyacınız olanı çıkarın, istediğiniz gibi filtreleyin
Duraklat/Devam Et Büyük taramaları istediğiniz zaman durdurun ve devam ettirin
Scrapy her şey için Screaming Frog'un yerini almayacak. Hızlı denetimler GUI'de hâlâ daha hızlı. Ancak büyük ölçekli taramalar, otomasyon ve özel çıkarma için araç setinizde bulundurmaya değer.

Kurulum

Kurulum

Scrapy Python üzerinde çalışır. Her şeyi temiz tutmak için sanal ortam kullanın:

Debian/Ubuntu:

sudo apt install python3.11-venv
python3 -m venv venv
source venv/bin/activate
pip install scrapy

macOS:

python3 -m venv venv
source venv/bin/activate
pip install scrapy

Windows:

python -m venv venv
venv\Scripts\activate
pip install scrapy
Sanal Ortamlar Önemlidir
Her zaman venv kullanın. Global kurulum bağımlılık çakışmalarına neden olur ve tekrarlanabilirliği bozar.

Proje Oluşturma

Scrapy kuruluyken:

scrapy startproject myproject
cd myproject
scrapy genspider sitename example.com

Bu şunları oluşturur:

myproject/
    scrapy.cfg
    myproject/
        __init__.py
        items.py
        middlewares.py
        pipelines.py
        settings.py
        spiders/
            __init__.py
            sitename.py

Spider kodu spiders/sitename.py‘ye gider. Yapılandırma settings.py‘de bulunur.

Nazik Tarama için Ayarlar

Kritik

Herhangi bir şey çalıştırmadan önce settings.py‘yi yapılandırın. Engellenmek, yavaş taramadan daha fazla zaman kaybettirir.

# Nazik tarama
CONCURRENT_REQUESTS_PER_DOMAIN = 5
DOWNLOAD_DELAY = 1
ROBOTSTXT_OBEY = True

# AutoThrottle - sunucu yanıtına göre hızı ayarlar
AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_START_DELAY = 5
AUTOTHROTTLE_MAX_DELAY = 60
AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
AUTOTHROTTLE_DEBUG = True

# Güvenlik limitleri
CLOSESPIDER_PAGECOUNT = 10000

# Çıktı
FEED_EXPORT_ENCODING = "utf-8"
AutoThrottle etkinken, 5 eşzamanlı istek makul bir başlangıç noktasıdır. Sunucu zorlanırsa AutoThrottle otomatik olarak geri çekilir. AutoThrottle olmadan, 1-3 ile daha düşük başlayın.

AutoThrottle

AutoThrottle, sunucu yanıt sürelerini izler ve tarama hızını otomatik olarak ayarlar:

  • Hızlı yanıtlar → hızlanır
  • Yavaş yanıtlar → yavaşlar
  • Hatalar/zaman aşımları → önemli ölçüde yavaşlar

Screaming Frog’un sabit gecikmelerinin aksine, gerçek sunucu koşullarına uyum sağlar.

Durum Kodu İşleme

Varsayılan olarak, Scrapy’nin HttpErrorMiddleware’i 2xx olmayan yanıtları sessizce düşürür. Bu, 404’lerin, 301’lerin, 500’lerin callback’inize ulaşmadan atıldığı anlamına gelir. Taramanız %100 200 durum kodu gösterebilir, site mükemmel olduğu için değil, hatalar filtrelendiği için.

Tüm durum kodlarını yakalamak için spider sınıfınıza bunu ekleyin:

handle_httpstatus_list = [200, 301, 302, 403, 404, 500, 502, 503]

Screaming Frog varsayılan olarak tüm durum kodlarını yakalar. Bu ayar Scrapy’yi bu davranışla uyumlu hale getirir.

Gerçek Dünya Performansı

Kıyaslamalar

5 eşzamanlı istek ve AutoThrottle etkinken test taramasından gerçek rakamlar:

Tarama İlerlemesi Sayfa/Dakika Notlar
0-200 sayfa 14-22 Rampa
200-500 sayfa 10-12 Stabilize oluyor
500-1.000 sayfa 7-10 AutoThrottle ayarlanıyor
1.000+ sayfa 5-7 Sabit durum
Hız vs. Güvenilirlik
Bu hızlar yavaş görünüyor. Mesele bu. AutoThrottle sunucu sağlığını ham hızın önüne koyar. Engellenmek ve yeniden başlamak, metodik bir taramadan daha fazla zaman kaybettirir.

Özellik Karşılaştırması

Özellik Screaming Frog Scrapy
Maliyet Ücretsiz <500 URL, ~259$/yıl Ücretsiz, açık kaynak
Maks tarama boyutu Bellek sınırlı Disk destekli kuyruklar
Özelleştirme Sınırlı yapılandırma seçenekleri Tam Python kodu
Zamanlama Manuel veya üçüncü taraf Yerel CLI, cron’lanabilir
Duraklat/Devam Et Evet Evet (JOBDIR ile)
Öğrenme eğrisi Düşük (GUI) Orta (kod)
Hız sınırlama Temel sabit gecikmeler AutoThrottle (uyarlanabilir)
JavaScript renderlama İsteğe bağlı (Chrome) İsteğe bağlı (playwright/splash)
Durum kodları Varsayılan olarak tümü Yapılandırma gerektirir
Alt alan filtreleme GUI onay kutuları Kod (esnek regex)
Dışa aktarma formatları CSV, Excel, vb. JSON, CSV, XML, özel
CI/CD entegrasyonu Zor Yerel

URL Filtreleme

Hassas Kontrol

Screaming Frog onay kutuları kullanır. Scrapy kod kullanır. Değiş tokuş, hassasiyet için öğrenme eğrisidir.

Uluslararası yolları hariç tutma:

import re
from urllib.parse import urlparse

class MySiteSpider(scrapy.Spider):
    name = "mysite"
    allowed_domains = ["example.com", "www.example.com"]
    start_urls = ["https://www.example.com/"]

    # /uk/, /fr/, /de/ gibi uluslararası yolları atla
    EXCLUDED_PATTERNS = re.compile(
        r"/(in|au|th|es|hk|sg|ph|my|ca|cn|uk|kr|id|fr|vn|de|jp|nl|it|tw)/"
    )

    def filter_links(self, links):
        filtered = []
        for link in links:
            hostname = urlparse(link.url).hostname or ""
            if hostname not in ("example.com", "www.example.com"):
                continue
            if self.EXCLUDED_PATTERNS.search(link.url):
                continue
            filtered.append(link)
        return filtered

URL desenleri, sorgu parametreleri, yanıt başlıkları, sayfa içeriği veya herhangi bir kombinasyona göre filtreleyebilirsiniz.

Duraklat ve Devam Et

Temel

1.000 sayfanın üzerindeki taramalar için, JOBDIR ile duraklat/devam et’i etkinleştirin:

scrapy crawl myspider -o output.json -s JOBDIR=crawl_state

Scrapy durumu crawl_state/‘e kaydeder. Duraklatmak için Ctrl+C‘ye basın. Devam etmek için aynı komutu çalıştırın.

Üretim taramaları için her zaman JOBDIR kullanın. Ağ sorunlarına, sistem yeniden başlatmalarına veya sadece gün için durmanız gerektiğinde koruma sağlar.

Durum, bekleyen URL’leri, görülen URL’leri ve istek kuyruğunu içerir. Bu, dosya tabanlı olduğu ve sistem yeniden başlatmalarını atladığı için Screaming Frog’un kaydet/yükle özelliğinden daha sağlamdır.

JavaScript Renderlama

Scrapy sadece ham HTML getirir. JavaScript renderlamaz. Bu, curl‘ün döndürdüğüyle aynıdır.

Çoğu SEO taraması için bu iyidir:

  • Meta etiketleri, canonical’lar ve h1’ler genellikle ilk HTML’dedir
  • Arama motorları öncelikle sunucu tarafında renderlanan içeriği indexler
  • Çoğu e-ticaret ve içerik sitesi sunucu tarafında renderlenir

Hedef siteniz içeriği istemci tarafında renderlıyorsa, seçenekleriniz var:

Paket Notlar
scrapy-playwright Chromium/Firefox/WebKit kullanır. Modern JS siteleri için önerilir
scrapy-splash Hafif, Docker tabanlı renderlayıcı
scrapy-selenium Eski yaklaşım, hala çalışır

JS renderlama önemli ölçüde daha yavaş ve kaynak yoğundur. Sadece site gerektiriyorsa ekleyin.

Screaming Frog benzer bir değiş tokuşa sahiptir. JavaScript renderlamayı etkinleştirmek arka planda Chrome kullanır ve taramaları önemli ölçüde yavaşlatır.

Bellek Yönetimi

Tam alan çıkarma ile ~1.300 sayfada:

  • Bellek: ~265 MB
  • CPU: ~%4

JOBDIR kullanmak istek kuyruklarını diske taşır ve belleği düşük tutar. Çok büyük taramalar (100k+ URL) için bu ayarları ekleyin:

MEMUSAGE_LIMIT_MB = 1024
MEMUSAGE_WARNING_MB = 800
SCHEDULER_DISK_QUEUE = 'scrapy.squeues.PickleFifoDiskQueue'
SCHEDULER_MEMORY_QUEUE = 'scrapy.squeues.FifoMemoryQueue'

Bu, bellek kullanımını sınırlar ve zamanlayıcı için disk destekli kuyrukları zorlar.

Çıktı Verileri

Özelleştirilebilir

Temel spider çıktısı:

{
    "url": "https://www.example.com/page/",
    "title": "Sayfa Başlığı Burada",
    "status": 200
}

SEO taramaları için, Screaming Frog’un dışa aktardığına benzer alanlar istersiniz:

def parse_page(self, response):
    yield {
        "url": response.url,
        "status": response.status,
        "title": response.css("title::text").get(),
        "meta_description": response.css("meta[name='description']::attr(content)").get(),
        "meta_robots": response.css("meta[name='robots']::attr(content)").get(),
        "h1": response.css("h1::text").get(),
        "canonical": response.css("link[rel='canonical']::attr(href)").get(),
        "og_title": response.css("meta[property='og:title']::attr(content)").get(),
        "og_description": response.css("meta[property='og:description']::attr(content)").get(),
        "word_count": len(response.text.split()) if response.status == 200 else None,
        "content_type": response.headers.get("Content-Type", b"").decode("utf-8", errors="ignore"),
    }

İhtiyacınıza göre alan ekleyin veya kaldırın. CSS seçicileri herhangi bir sayfa içi öğe için çalışır.

Dışa aktarma formatları: JSON (-o output.json), JSON Lines (-o output.jsonl), CSV (-o output.csv), XML (-o output.xml).

JSON Lines büyük taramalar için en iyisidir. Dosyalar tarama sırasında satır satır geçerlidir, böylece tail -f ile izleyebilirsiniz. Standart JSON, tarama tamamlanana kadar geçerli değildir.

Screaming Frog → Scrapy

Çeviri Rehberi

SF iş akışlarını Scrapy’ye eşleme:

Screaming Frog Eylemi Scrapy Karşılığı
Yeni tarama başlat scrapy crawl spidername
Tarama gecikmesi ayarla Ayarlarda DOWNLOAD_DELAY
Eşzamanlı thread’leri sınırla CONCURRENT_REQUESTS_PER_DOMAIN
robots.txt’ye uy ROBOTSTXT_OBEY = True
CSV’ye dışa aktar -o output.csv
Taramayı kaydet/yükle -s JOBDIR=crawl_state
Alt alanları filtrele Spider’da kod (regex)
Özel çıkarma parse()‘da CSS/XPath seçiciler

Zihniyet değişimleri:

  1. Yapılandırma koddur. Onay kutularını tıklamak yerine settings.py‘yi düzenleyin.
  2. Çıkarma açıktır. Hangi verilerin yakalanacağını siz yazarsınız.
  3. Zamanlama yereldir. cron veya CI/CD’ye komutlar ekleyin.
  4. Hata ayıklama loglar demektir. Neler olduğunu görmek için AUTOTHROTTLE_DEBUG‘ı etkinleştirin.

Tam İş Akışı

Yukarıdaki standart ayarlarla, Scrapy’yi 15 dakikadan kısa sürede kurabilir ve taramaya başlayabilirsiniz:

python3 -m venv venv
source venv/bin/activate  # Windows'ta venv\Scripts\activate
pip install scrapy
scrapy startproject urlcrawler
cd urlcrawler
scrapy genspider mysite example.com
# settings.py'yi nazik tarama yapılandırmasıyla düzenleyin
# spiders/mysite.py'yi parse mantığınızla düzenleyin
scrapy crawl mysite -o urls.jsonl -s JOBDIR=crawl_state

Scrapy Shell

Özel yapılandırmalar oluştururken, seçicilerinizi ve ayarlarınızı etkileşimli olarak test etmek için Scrapy Shell‘i kullanın:

scrapy shell "https://example.com"

Bu, yanıt zaten yüklenmiş olarak etkileşimli bir Python konsolu açar. Spider’ınıza eklemeden önce CSS ve XPath seçicileri gerçek zamanlı test edin:

>>> response.css('title::text').get()
'Example Domain'
>>> response.xpath('//h1/text()').get()
'Example Domain'

Scrapy Shell, iterasyon süresini önemli ölçüde azaltır. Tam taramalar çalıştırmadan çıkarma mantığını doğrulayın.

Tam Spider Şablonu

URL filtreleme, durum kodu işleme ve tam SEO alan çıkarma ile üretime hazır bir spider:

import re
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from urllib.parse import urlparse


class SEOSpider(CrawlSpider):
    name = "seospider"
    allowed_domains = ["example.com"]
    start_urls = ["https://www.example.com"]

    # Capture all HTTP status codes, not just 2xx
    handle_httpstatus_list = [200, 301, 302, 403, 404, 500, 502, 503]

    # URL patterns to exclude
    EXCLUDED_PATTERNS = re.compile(
        r"/(in|au|th|es|hk|sg|ph|my|ca|cn|uk|kr|id|fr|vn|de|jp|nl|it|tw)/"
    )

    rules = (
        Rule(
            LinkExtractor(allow=()),
            callback="parse_page",
            follow=True,
            process_links="filter_links",
        ),
    )

    def filter_links(self, links):
        filtered = []
        for link in links:
            parsed = urlparse(link.url)
            hostname = parsed.hostname or ""

            if hostname not in ("example.com", "www.example.com"):
                continue

            if self.EXCLUDED_PATTERNS.search(link.url):
                continue

            filtered.append(link)
        return filtered

    def parse_page(self, response):
        yield {
            "url": response.url,
            "status": response.status,
            "title": response.css("title::text").get(),
            "meta_description": response.css("meta[name='description']::attr(content)").get(),
            "meta_robots": response.css("meta[name='robots']::attr(content)").get(),
            "h1": response.css("h1::text").get(),
            "canonical": response.css("link[rel='canonical']::attr(href)").get(),
            "og_title": response.css("meta[property='og:title']::attr(content)").get(),
            "og_description": response.css("meta[property='og:description']::attr(content)").get(),
            "word_count": len(response.text.split()) if response.status == 200 else None,
            "content_type": response.headers.get("Content-Type", b"").decode("utf-8", errors="ignore"),
        }

example.com‘u hedef alan adınızla değiştirin. EXCLUDED_PATTERNS‘ı sitenizin URL yapısına göre ayarlayın.

Hangisini Ne Zaman Kullanmalı

Screaming Frog:

Scrapy:

  • 10.000 URL’nin üzerinde siteler
  • Otomatik, zamanlanmış taramalar
  • Özel çıkarma ihtiyaçları
  • CI/CD entegrasyonu
  • Bellek kısıtlamaları
  • Sürüm kontrollü yapılandırmalar

Sonuç

Scrapy, Screaming Frog’dan daha dik bir kurulum eğrisine sahip, ancak GUI tarayıcılarının dayattığı pratik sınırları kaldırır. URL sınırları yok, lisans ücretleri yok, daha düşük bellek kullanımı ve yerel otomasyon.

Küçük başlayın. Bildiğiniz bir siteyi tarayın. Muhafazakar ayarlar kullanın. Çıktıyı Screaming Frog ile karşılaştırın. Veriler eşleşecek, ancak ölçeklenen bir aracınız olacak.