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 gider | Orası 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 bilgileri | Proxy URL’sinde; Scrapy bunları Proxy-Authorization başlığına dönüştürür |
| SOCKS5 | Varsayılan HTTP/1.1 yöneticisiyle değil; Scrapy 2.17+ optional HttpxDownloadHandler aracılığıyla SOCKS destekler. HTTP 7777 portu en basittir |
| Rotasyon | Her yeni bağlantı için yeni çıkış; her istek için benzersiz oturum ID’si farklı IP verir |
| Nazik kullanım | ROBOTSTXT_OBEY, CONCURRENT_REQUESTS_PER_DOMAIN, AUTOTHROTTLE_ENABLED |
| Yeniden denemeler | 429 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.
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 NoneHangi 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.
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 = 45Sayfalama 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.
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.
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?
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.