Die einfachste Version#
Klassifizieren Sie die Antwort, bevor Sie es erneut versuchen. Ein 403 kann auf eine Zugriffsregel hinweisen, die eine andere IP nicht auflöst. Beachten Sie bei 429 Retry-After und reduzieren Sie die Anforderungsrate. Verwenden Sie einen begrenzten Backoff für vorübergehende Verbindungs- oder Serverausfälle. Wiederholen Sie Vorgänge zur Statusänderung nur dann, wenn Sie doppelte Aktionen verhindern können.
import scrapy
PROXY = "http://USER-cc-us:PASS@res.proxy-cyber.com:9000"
class PricesSpider(scrapy.Spider):
name = "prices"
start_urls = ["https://example.com/catalog"]
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(url, meta={"proxy": PROXY})
def parse(self, response):
for href in response.css("a.product::attr(href)").getall():
yield response.follow(href, callback=self.parse_product, meta={"proxy": PROXY})
def parse_product(self, response):
yield {"url": response.url, "price": response.css(".price::text").get()}Eine Middleware für Sticky Sessions pro Item#
import hashlib
class Proxy CyberMiddleware:
GATEWAY = "res.proxy-cyber.com:9000"
def __init__(self, user, password, country):
self.user, self.password, self.country = user, password, country
@classmethod
def from_crawler(cls, crawler):
s = crawler.settings
return cls(s.get("KEY_PROXY_USER"), s.get("KEY_PROXY_PASS"), s.get("KEY_PROXY_COUNTRY", "us"))
def process_request(self, request, spider):
# Sticky when the request carries a session key (e.g. one per product flow), rotating otherwise
key = request.meta.get("session_key")
user = f"{self.user}-cc-{self.country}"
if key:
sid = hashlib.sha1(key.encode()).hexdigest()[:12]
user += f"-sid-{sid}-ttl-10m"
request.meta["proxy"] = f"http://{user}:{self.password}@{self.GATEWAY}"DOWNLOADER_MIDDLEWARES = {
"myproject.middlewares.Proxy CyberMiddleware": 350, # before HttpProxyMiddleware (750)
}
KEY_PROXY_USER = "USER"
KEY_PROXY_PASS = "PASS"
KEY_PROXY_COUNTRY = "de"
CONCURRENT_REQUESTS = 32
CONCURRENT_REQUESTS_PER_DOMAIN = 8
AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_TARGET_CONCURRENCY = 4.0
DOWNLOAD_TIMEOUT = 45
RETRY_ENABLED = True
RETRY_TIMES = 2
RETRY_HTTP_CODES = [408, 429, 500, 502, 503, 504, 522, 524]
COMPRESSION_ENABLED = TrueDie Wiederverwendung von Verbindungen und die IP-Zuweisung sind unterschiedliche Steuerelemente. Eine Clientsitzung verwendet Sockets wieder. Nur das zugewiesene Gateway bestimmt die Rotation und das Sticky-Session-Verhalten. Verwenden Sie die mit Ihrem Dienst bereitgestellten Sitzungsparameter und überprüfen Sie den Exit über mehrere Anfragen hinweg. Das Schließen eines Sockets oder das Senden von Connection: close garantiert keine andere IP.
Die Rechnung unten halten#
- Scrapy lädt keine Bilder oder Skripte; Nur HTML und JSON, daher kostet eine Seite ihre HTML-Größe.
- Komprimierung (Standard) aktivieren und vermeiden
Splashoder Browser-Rendering, es sei denn, die Daten benötigen es. - Cache mit
HTTPCACHE_ENABLED = Truewährend der Entwicklung, sodass Sie beim Debuggen von Selektoren nicht dafür bezahlen, dieselben Seiten erneut abzurufen.
Höflichkeit pro Domain#
Ein Pool ist eine Möglichkeit, viele höfliche Besucher zu haben, nicht einen unhöflichen. CONCURRENT_REQUESTS_PER_DOMAIN und AutoThrottle sorgen dafür, dass jedes Ziel pro Ausfahrt mit einer für Menschen plausiblen Rate erreicht wird. die akzeptable Nutzungsrichtlinien verbietet alles, was wie ein Angriff aussieht.
Fragen, die Menschen stellen#
Brauche ich Scrapy-Rotating-Proxys?
Nicht mit einem Gateway: Bei jeder neuen Verbindung erfolgt die Rotation auf der Seite des Proxy Cybers. Dieses Paket verwaltet Listen statischer Proxys; Mit res.proxy-cyber.com muss ein Proxy konfiguriert werden.
Wie verwende ich ein anderes Land pro Anfrage?
Legen Sie request.meta["country"] im Spider fest und lesen Sie es in der Middleware, um den Parameter -cc- zu erstellen. Im Beispiel wird der Kürze halber eine einzige Einstellung verwendet.