Tanpa KYC — tanpa ID, tanpa selfie, tanpa dokumen. Bayar dengan crypto: BTC, USDT, USDC, ETH, SOL, LTC
Bahasa: Bahasa Indonesia
Mulai sekarang

Dokumentasi · Scrapy 2.x · middleware · AutoThrottle

Middleware proxy Scrapy untuk rotasi proxy residensial

Middleware downloader sepanjang 30 baris yang memilih negara dan sesi per permintaan, serta pengaturan agar crawl tetap sopan: robots.txt, konkurensi per domain, AutoThrottle dan retry.

Terakhir diperbarui: · 5 baca dalam menit

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 proxyrequest.meta["proxy"], disetel oleh middleware Anda
Urutan MiddlewareMiddleware Anda di bawah 750, prioritas middleware HttpProxyMiddleware bawaan
KredensialDalam URL proxy; Scrapy mengubahnya menjadi header Proxy-Authorization
SOCKS5Tidak dengan handler HTTP/1.1 default; Scrapy 2.17+ mendukung SOCKS lewat HttpxDownloadHandler opsional. Port HTTP 7777 paling sederhana
RotasiExit baru per koneksi baru; ID sesi unik per permintaan biasanya memberi IP berbeda
Kepatuhan Sopan santunROBOTSTXT_OBEY, CONCURRENT_REQUESTS_PER_DOMAIN, AUTOTHROTTLE_ENABLED
Retry429 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.

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

Pengaturan 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.

settings.py (kutipan)
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

Bagaimana 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.

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,
        }

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.

settings.py untuk scrapy-playwright
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?

TunnelError: Could not open CONNECT tunnel berarti proxy menolak atau gagal permintaan CONNECT untuk situs HTTPS. Status pada pesan memberi tahu alasannya: 407 terkait kredensial, 502 atau 504 terkait exit atau target. Lihat halaman 407 dan 502.

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.

Dari US$0,50/GB · tanpa KYC

Mulai sekarang