KYC olmadan — kimlik, selfie veya belge istemez. Kripto ile ödeyin: BTC, USDT, USDC, ETH, SOL, LTC
Dil: Türkçe
Başlayın

Dokümantasyon · Scrapy 2.x · ara katman · AutoThrottle

Scrapy döner konut proxy ara katmanı

İstek başına ülke ve oturum seçen 30 satırlık indirici ara katmanı, ve kibar tarama için ayarlar: robots.txt, domain başına eşzamanlılık, AutoThrottle ve yeniden denemeler.

Son güncelleme: · 5 dk okuma

Hızlı cevap

Scrapy’de dönen proxyler nasıl kullanılır?

Küçük bir indirici ara katmanında request.meta["proxy"] değerini http://USERNAME:[email protected]:7777 yapın; bu ara katman Scrapy’nin HttpProxyMiddleware önünde çalışır ve kimlik bilgilerini gönderir. CrawlRelay konut proxylerinde ülke ve kalıcı oturum kullanıcı adında yer alır; böylece tek bir ara katman ikisini yönetir. Trafik ücreti $0,50/GB ile 50 GB’dan başlar. KYC olmadan kripto ile ödenir.

Scrapy kurulumu bir bakışta

Proxy nereye giderOrası request.meta["proxy"], ara katmanınız tarafından ayarlanır
Ara katman sırasıAra katmanınız 750’nin altında, dahili HttpProxyMiddleware önceliğinde
Kimlik bilgileriProxy URL’sinde; Scrapy bunları Proxy-Authorization başlığına dönüştürür
SOCKS5Varsayılan HTTP/1.1 yöneticisiyle değil; Scrapy 2.17+ optional HttpxDownloadHandler aracılığıyla SOCKS destekler. HTTP 7777 portu en basittir
RotasyonHer yeni bağlantı için yeni çıkış; her istek için benzersiz oturum ID’si farklı IP verir
Nazik kullanımROBOTSTXT_OBEY, CONCURRENT_REQUESTS_PER_DOMAIN, AUTOTHROTTLE_ENABLED
Yeniden denemeler429 ve 5xx kodları varsayılan RETRY_HTTP_CODES içindedir; Retry-After varsayılan olarak okunmaz

Proxy ara katmanını nasıl yazarım?

Sınıfı middlewares.py içine koyun. Kullanıcı adını ayarlardan ve üç isteğe bağlı meta anahtarı: proxy_country, proxy_session ve proxy_ttl üzerinden oluşturur. proxy_session olmayan istekler döner; proxy_session="new" olan istekler yeni oturum alır, yani genellikle farklı bir çıkış IP’si; sabit oturum ID’li istek aynı akışın diğer istekleriyle çıkış paylaşır. Ara katman her geçişte (yeniden denemeler dahil) proxy’sini yeniden hesaplar ve başka bir kodun ayarladığı proxy’i değiştirmez. CRAWLRELAY_USER yoksa, tarama IP’niz üzerinden başlamaya çalışmak yerine başlatmada durur.

middlewares.py
import uuid
from urllib.parse import quote


class CrawlRelayProxyMiddleware:
    """Sets request.meta["proxy"]; Scrapy's HttpProxyMiddleware then sends the credentials."""

    def __init__(self, user, password, country):
        self.user, self.password, self.country = user, password, country

    @classmethod
    def from_crawler(cls, crawler):
        s = crawler.settings
        if not s.get("CRAWLRELAY_USER"):
            # Fail loudly: NotConfigured would only disable the middleware and crawl from your own IP
            raise ValueError("CRAWLRELAY_USER is not set: refusing to crawl without the proxy")
        return cls(s.get("CRAWLRELAY_USER"), s.get("CRAWLRELAY_PASSWORD", ""), s.get("CRAWLRELAY_COUNTRY", "us"))

    def process_request(self, request, spider=None):
        if "proxy" in request.meta and not request.meta.get("_crawlrelay"):
            return None  # a proxy set by other code: leave it alone
        parts = [self.user, "country", request.meta.get("proxy_country", self.country)]
        session = request.meta.get("proxy_session")
        if session == "new":  # a fresh session for this request (and for each of its retries)
            session = uuid.uuid4().hex[:12]
        if session:
            parts += ["session", session, "ttl", str(request.meta.get("proxy_ttl", 10))]
        username = "-".join(parts)
        request.meta["proxy"] = "http://%s:%[email protected]:7777" % (
            quote(username, safe=""), quote(self.password, safe=""))
        request.meta["_crawlrelay"] = True
        return None

Hangi Scrapy ayarları proxyli taramaları kibar ve hızlı tutar?

Proxyler isteklerinizi birçok IP’ye yayar, ama hedef toplam hızınızı görür. Bu ayarlar her domainin sürdürülebilir hızda kalmasını sağlar ve yanıtlar yavaşladığında AutoThrottle’un kendiliğinden yavaşlamasına izin verir. Yeni Scrapy projelerinin zaten ayarladığı ROBOTSTXT_OBEY = True’u koruyun.

settings.py (alıntı)
import os

BOT_NAME = "myproject"
ROBOTSTXT_OBEY = True
USER_AGENT = "ExampleCrawler/1.0 (+https://example.com/crawler-info)"

CRAWLRELAY_USER = os.environ.get("CRAWLRELAY_USER")  # e.g. the username from your dashboard
CRAWLRELAY_PASSWORD = os.environ.get("CRAWLRELAY_PASSWORD")
CRAWLRELAY_COUNTRY = "us"

DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.CrawlRelayProxyMiddleware": 350,  # runs before HttpProxyMiddleware (750)
}

CONCURRENT_REQUESTS = 32
CONCURRENT_REQUESTS_PER_DOMAIN = 4
AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_START_DELAY = 1.0
AUTOTHROTTLE_MAX_DELAY = 30.0
AUTOTHROTTLE_TARGET_CONCURRENCY = 2.0

RETRY_ENABLED = True
RETRY_TIMES = 3
RETRY_HTTP_CODES = [429, 500, 502, 503, 504, 522, 524, 408]
DOWNLOAD_TIMEOUT = 45

Sayfalama için tek bir IP'yi nasıl sabit tutarım ve öge sayfalarında döndürme yaparım?

Önceki sayfaya bağlı olan bir akışın isteklerinde sabit bir proxy_session geçirin, bağımsız sayfalarda ise hiçbir şey geçirmeyin. Aşağıdaki örümcek, scraping pratiği için yayınlanan sandbox sitesi books.toscrape.com üzerinde çalışır.

spiders/catalog.py
import scrapy


class CatalogSpider(scrapy.Spider):
    name = "catalog"
    start_urls = ["https://books.toscrape.com/"]

    def parse(self, response):
        for href in response.css("article.product_pod h3 a::attr(href)").getall():
            # Product pages are independent: rotating exits
            yield response.follow(href, callback=self.parse_item)
        next_page = response.css("li.next a::attr(href)").get()
        if next_page:
            # The listing flow keeps one sticky exit for 30 minutes
            yield response.follow(next_page, callback=self.parse,
                                  meta={"proxy_session": "listing1", "proxy_ttl": 30})

    def parse_item(self, response):
        yield {
            "title": response.css("div.product_main h1::text").get(),
            "price": response.css("p.price_color::text").get(),
            "url": response.url,
        }

Scrapy bağlantıları yeniden kullanıyor mu ve bu döndürmeyi engelliyor mu?

Evet, Scrapy bağlantıları canlı tutar ve her proxy ile hedef sunucu için yeniden kullanır, böylece bir bağlantıdaki ardışık istekler aynı çıkışı paylaşır. Çoğu tarama için bu uygundur: Scrapy, site başına CONCURRENT_REQUESTS_PER_DOMAIN bağlantı açar ve her yeni bağlantıya genellikle farklı bir konut proxy atanır.

Bir istek yeni bir IP üzerinden gitmeli ise, örneğin başarısız bir çıkıştan sonra 502 alındığında, response.request.replace(meta={**response.meta, "proxy_session": "new"}, dont_filter=True) ile yeniden gönderin. Middleware yeni bir oturum kullanıcı adı oluşturur, farklı kullanıcı adı farklı bağlantı havuzu anlamına gelir, böylece Scrapy yeni bağlantı açar ve geçit normalde başka bir çıkış verir.

Scrapy'de 429 yanıtlarında Retry-After nasıl dikkate alınır?

Scrapy'nin yerleşik RetryMiddleware mekanizması 429'u tekrar dener ama Retry-After gecikmesini beklemez. AutoThrottle zamanla alanı yavaşlatır, bu genellikle yeterlidir. Uzun Retry-After değerleri gönderen API'lar için başlığı okuyan ve gecikmeli yeniden denemeyi planlayan küçük bir middleware ekleyin veya o alan için CONCURRENT_REQUESTS_PER_DOMAIN değerini düşürün. 429 sayfası başlığın ne anlama geldiğini açıklar.

scrapy-playwright ile proxy nasıl kullanılır?

JavaScript gerektiren sayfalar için scrapy-playwright, Playwright'in başlatma seçeneklerini bir ayar yoluyla iletir. Kimlik bilgilerini ayrı alanlar olarak verin: Chromium, sunucu URL'si içindeki kimlik bilgilerini yok sayar. Oturum açılmamış akışları birkaç sayfa boyunca işliyorsanız, her yapışkan oturum için bir bağlam kullanın.

scrapy-playwright için settings.py
import os

DOWNLOAD_HANDLERS = {
    "http": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
    "https": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
}
TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor"

PLAYWRIGHT_LAUNCH_OPTIONS = {
    "proxy": {
        "server": "http://gw.crawlrelay.com:7777",
        "username": os.environ.get("CRAWLRELAY_USER", "USERNAME") + "-country-us",
        "password": os.environ.get("CRAWLRELAY_PASSWORD", "PASSWORD"),
    },
}

Scrapy ve proxyler: sorular

scrapy-rotating-proxies veya proxy listesine ihtiyacım var mı?

Hayır. Bu paketler bireysel proxy adreslerinin listesini döndürür ve başarısız olanları engeller. Bir konut proxy geçidi ile döndürme tek bir adresin arkasında gerçekleşir: her yeni bağlantı genellikle farklı bir konut proxy alır. Sadece request.meta["proxy"] alan tek bir middleware yeterlidir.

Scrapy neden proxy ile TunnelError gösteriyor?

TunnelError: Could not open CONNECT tunnel, proxy'nin bir HTTPS sitesi için CONNECT isteğini reddettiği veya başarısız olduğu anlamına gelir. Mesajdaki durum kodu sebebini gösterir: 407 kimlik bilgisi sorunu, 502 veya 504 çıkış ya da hedef kaynaklıdır. 407 ve 502 sayfalarına bakın.

Her alan için kaç eşzamanlı istek kullanmalıyım?

Alan başına 2 ile 4 arasında başlayın ve AutoThrottle’un ayarlamasına izin verin. 429, 403 ve 5xx oranları sabit kaldığı sürece sayıyı artırın ve sitenin yanıt sürelerini takip edin. Büyük siteler küçük sitelere göre daha fazla eşzamanlılığa dayanıklıdır; küçük bir site istekler arasında gecikme ve tek bağlantı gerektirebilir.

Daha fazla veri almak için ROBOTSTXT_OBEY devre dışı bırakılmalı mı?

Hayır. robots.txt, bir sitenin otomatik istemcilerin hangi yolları getirebileceğini bildirdiği dosyadır ve 2022’de RFC 9309 formatı standartlaştırılmıştır. Bunu görmezden gelmek yasal ve etik riski artırır ve sitede engellenen içeriğe ulaşmak için kullanılırsa bizim Kabul Edilebilir Kullanım Politikamıza aykırıdır.

Bir Scrapy taraması ne kadar trafik kullanır?

Scrapy sadece HTML indirir, sayfalar genellikle sıkıştırılmış halde onlarca kilobayt civarındadır. Çalışma sonunda Scrapy'nin yazdırdığı istatistiklerdeki downloader/response_bytes değerini kontrol edin ve cevap sayısına bölün. Bant genişliği rehberi bunu maliyete çevirir.

Scrapy projenize konut IP'ler entegre edin

Test için $5,94, 10 GB ve $0,50/GB, 50 GB'ten.

$0,50/GB · KYC olmadan

Başlayın