Jawaban cepat
Bagaimana menggunakan proxy rotasi dengan Scrapy?
Atur request.meta["proxy"] ke http://USERNAME:[email protected]:7777 dalam middleware downloader kecil yang dijalankan sebelum HttpProxyMiddleware Scrapy; Scrapy lalu mengirimkan kredensial untuk Anda. Dengan proxy residensial CrawlRelay, negara dan sesi tetap masuk dalam username, sehingga satu middleware menangani keduanya. Biaya trafik US$0,50/GB mulai dari 50 GB. Dibayar dengan crypto, tanpa KYC.
Setup Scrapy secara singkat
| Dimana letak proxy | request.meta["proxy"], disetel oleh middleware Anda |
|---|---|
| Urutan Middleware | Middleware Anda di bawah 750, prioritas middleware HttpProxyMiddleware bawaan |
| Kredensial | Dalam URL proxy; Scrapy mengubahnya menjadi header Proxy-Authorization |
| SOCKS5 | Tidak dengan handler HTTP/1.1 default; Scrapy 2.17+ mendukung SOCKS lewat HttpxDownloadHandler opsional. Port HTTP 7777 paling sederhana |
| Rotasi | Exit baru per koneksi baru; ID sesi unik per permintaan biasanya memberi IP berbeda |
| Kepatuhan Sopan santun | ROBOTSTXT_OBEY, CONCURRENT_REQUESTS_PER_DOMAIN, AUTOTHROTTLE_ENABLED |
| Retry | 429 dan 5xx ada dalam RETRY_HTTP_CODES default; Retry-After tidak dibaca secara default |
Bagaimana cara menulis middleware proxy?
Letakkan kelas di middlewares.py. Kelas membangun username dari pengaturan dan dari tiga kunci meta opsional: proxy_country, proxy_session dan proxy_ttl. Permintaan tanpa proxy_session akan berotasi; permintaan dengan proxy_session="new" mendapat sesi baru, jadi biasanya IP exit berbeda; permintaan dengan ID sesi tetap berbagi satu exit dengan permintaan lain dalam alur yang sama. Middleware menghitung ulang proxy setiap kali dilewati, termasuk retry, dan membiarkan proxy yang disetel kode lain tetap ada. Jika CRAWLRELAY_USER hilang, crawl berhenti saat mulai alih-alih berjalan dari IP Anda sendiri.
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 NonePengaturan Scrapy mana yang menjaga crawl memakai proxy tetap sopan dan cepat?
Proxy menyebarkan permintaan Anda ke banyak IP, tapi target masih melihat total kecepatan Anda. Pengaturan ini menjaga tiap domain berjalan dengan kecepatan yang wajar dan membiarkan AutoThrottle memperlambat sendiri saat respon melambat. Pertahankan ROBOTSTXT_OBEY = True, yang sudah disetel oleh proyek Scrapy baru.
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 = 45Bagaimana cara menjaga satu IP untuk pagination dan merotasi untuk halaman item?
Lewatkan proxy_session tetap pada permintaan dari aliran yang bergantung pada halaman sebelumnya, dan bukan pada halaman independen. Spider di bawah ini berjalan di books.toscrape.com, situs sandbox yang diterbitkan untuk latihan scraping.
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,
}Apakah Scrapy menggunakan kembali koneksi, dan apakah itu menghentikan rotasi?
Ya, Scrapy menjaga koneksi tetap hidup dan menggunakannya kembali per proxy dan host target, jadi permintaan berturut-turut pada satu koneksi berbagi exit. Untuk sebagian besar crawl itu tidak masalah: Scrapy membuka hingga CONCURRENT_REQUESTS_PER_DOMAIN koneksi per situs, dan tiap koneksi baru biasanya mendapatkan IP proxy residensial yang berbeda.
Saat permintaan harus keluar melalui IP baru, misalnya retry setelah mendapatkan 502 dari exit yang gagal, kirim ulang dengan response.request.replace(meta={**response.meta, "proxy_session": "new"}, dont_filter=True). Middleware membuat username sesi baru, username berbeda berarti kolam koneksi berbeda, jadi Scrapy membuka koneksi baru dan gateway biasanya menetapkan exit berbeda.
Bagaimana cara menghormati Retry-After pada respons 429 di Scrapy?
Scrapy built-in RetryMiddleware mencoba ulang untuk 429 tapi tidak menunggu delay Retry-After. AutoThrottle memperlambat domain secara bertahap, yang biasanya cukup. Untuk API dengan nilai Retry-After yang panjang, tambahkan middleware kecil yang membaca header dan menjadwalkan retry dengan delay, atau turunkan CONCURRENT_REQUESTS_PER_DOMAIN untuk domain tersebut. Halaman 429 menjelaskan arti header tersebut.
Bagaimana cara menggunakan proxy dengan scrapy-playwright?
Untuk halaman yang membutuhkan JavaScript, scrapy-playwright meneruskan opsi peluncuran Playwright melalui setting. Berikan kredensial sebagai field terpisah: Chromium mengabaikan kredensial yang tertulis di dalam URL server. Gunakan satu konteks per sesi sticky jika kamu merender alur logout yang mencakup beberapa halaman.
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 dan proxy: pertanyaan
Apakah saya perlu scrapy-rotating-proxies atau daftar proxy?
Tidak. Paket tersebut merotasi daftar alamat proxy individual dan memblokir yang gagal. Dengan gateway proxy residensial, rotasi terjadi di balik satu alamat: setiap koneksi baru biasanya mendapatkan IP proxy residensial berbeda. Middleware tunggal yang mengatur request.meta["proxy"] sudah cukup.
Mengapa Scrapy menampilkan TunnelError dengan proxy saya?
Berapa banyak permintaan bersamaan per domain yang sebaiknya saya gunakan?
Mulai dengan 2 sampai 4 per domain dan biarkan AutoThrottle menyesuaikan. Tingkatkan jumlah hanya jika persentase respons 429, 403, dan 5xx tetap stabil, dan perhatikan waktu respons situs. Situs besar toleran lebih banyak dibanding yang kecil; situs kecil mungkin perlu jeda antar permintaan dan satu koneksi.
Haruskah saya menonaktifkan ROBOTSTXT_OBEY untuk mendapatkan lebih banyak data?
Tidak. robots.txt adalah cara situs menyatakan jalur yang boleh diambil oleh klien otomatis, dan RFC 9309 menstandarisasi format ini sejak 2022. Mengabaikannya meningkatkan risiko hukum dan etika dan melanggar Acceptable Use Policy kami jika digunakan untuk mengakses konten yang dikeluarkan situs.
Berapa banyak trafik yang digunakan oleh crawl Scrapy?
Scrapy hanya mengunduh HTML, jadi halaman biasanya berukuran puluhan kilobyte tiap halaman, terkompresi. Periksa nilai downloader/response_bytes dalam statistik yang Scrapy cetak di akhir run dan bagi dengan jumlah respons. Panduan bandwidth mengubahnya menjadi perkiraan biaya.
Pasang IP proxy residensial ke proyek Scrapy kamu
US$5,94 untuk 10 GB untuk pengujian, US$0,50/GB dari 50 GB.