Panduan4 menit baca

Proxy Scrapy: pasang middleware, rotating, dan sesi sticky

Cara memasang residential proxy di Scrapy: lewat meta per request, downloader middleware, sesi sticky per alur, target negara, dan setting yang hemat kuota.

Untuk memakai proxy di Scrapy, isi request.meta["proxy"] dengan URL lengkap http://USERNAME:PASSWORD@proxy.waroengproxy.com:8000. Middleware bawaan Scrapy (HttpProxyMiddleware) yang aktif secara bawaan akan membaca username dan password dari URL itu, lalu mengirimnya ke proxy. Panduan ini membahas cara cepat untuk tes, cara rapi lewat middleware sendiri, kapan memakai sesi sticky, dan setting yang menjaga kuota tetap hemat.

Siapkan kredensial dan tes IP dulu

Ambil username dan password dari Generator proxy. Simpan sebagai environment variable, jangan ditulis langsung di kode yang ikut masuk Git. Kalau belum punya akun, daftar cukup memakai token akses, lalu isi saldo dengan QRIS.

Sebelum menulis spider sungguhan, pastikan proxy-nya jalan. HttpProxyMiddleware juga membaca environment variable https_proxy, jadi spider satu file di bawah ini bisa langsung dites tanpa mengubah proyek:

Python
# cekip.py
import scrapy
class CekIP(scrapy.Spider):
name = "cekip"
start_urls = ["https://ipinfo.io/json"]
def parse(self, response):
yield response.json()
# Git Bash / Linux / macOS:
# https_proxy="http://USERNAME-cc-ID:PASSWORD@proxy.waroengproxy.com:8000" scrapy runspider cekip.py
# PowerShell:
# $env:https_proxy="http://USERNAME-cc-ID:PASSWORD@proxy.waroengproxy.com:8000"; scrapy runspider cekip.py

Hasilnya menampilkan IP, kota, dan jaringan yang dilihat situs tujuan. Karena username memakai -cc-ID, negaranya harus Indonesia. Ganti ID dengan kode negara lain untuk menguji target lain.

Cara cepat: proxy per request lewat meta

Untuk satu atau dua request, pasang proxy langsung di meta:

Contoh
yield scrapy.Request(
"https://example.com/produk/1",
callback=self.parse_produk,
meta={"proxy": "http://USERNAME-cc-ID:PASSWORD@proxy.waroengproxy.com:8000"},
)

Cara ini praktis untuk eksperimen, tapi cepat berantakan kalau spider-nya banyak. Kredensial tersebar di banyak tempat dan susah diganti.

Cara rapi: downloader middleware sendiri

Middleware kecil di bawah ini memasang proxy ke semua request yang belum punya proxy. Prioritas 350 membuatnya jalan lebih dulu daripada HttpProxyMiddleware (prioritas 750), sehingga URL proxy sudah ada saat middleware bawaan memprosesnya. Ganti proyekku dengan nama proyek Scrapy-mu.

Python
# middlewares.py
import os
from urllib.parse import quote
USER = os.environ["WP_USER"]
PASS = quote(os.environ["WP_PASS"], safe="")
HOST = "proxy.waroengproxy.com:8000"
class WaroengProxyMiddleware:
def process_request(self, request, spider):
if "proxy" in request.meta:
return None # sudah diatur manual di spider
user = USER + "-cc-ID"
sesi = request.meta.get("sesi")
if sesi:
user += f"-s-{sesi}-ttl-600"
request.meta["proxy"] = f"http://{user}:{PASS}@{HOST}"
return None
# settings.py
DOWNLOADER_MIDDLEWARES = {
"proyekku.middlewares.WaroengProxyMiddleware": 350,
}

Password di-encode dengan quote supaya karakter seperti @ atau : tidak merusak URL. Request yang sudah punya meta["proxy"] dibiarkan, jadi kamu tetap bisa mengatur proxy khusus untuk request tertentu.

Rotating atau sticky di Scrapy

Tanpa parameter -s-, proxy bekerja dalam mode rotating: IP berganti dari jaringan. Perlu diingat, Scrapy memakai ulang koneksi, dan untuk situs https:// satu koneksi (tunnel CONNECT) terikat ke satu IP. Jadi beberapa request berurutan ke situs yang sama bisa saja keluar lewat IP yang sama walaupun mode-nya rotating. Untuk halaman publik yang berdiri sendiri, misalnya memantau harga, itu biasanya tidak masalah.

Mode sticky dipakai kalau situs butuh IP yang konsisten di beberapa request berurutan, misalnya alur yang menyimpan pilihan kota pengiriman di cookie lalu membuka halaman berikutnya. Middleware di atas menambahkan -s-<label>-ttl-600 kalau request membawa meta["sesi"]. Label yang sama berarti IP yang sama selama TTL, yaitu 1 sampai 86.400 detik (bawaan 60). Label hanya boleh huruf dan angka, tanpa tanda minus, karena tanda minus adalah pemisah di username.

Python
import secrets
def parse(self, response):
for href in response.css("a.toko::attr(href)").getall():
sesi = secrets.token_hex(4) # satu label = satu IP
yield response.follow(href, self.parse_toko,
meta={"sesi": sesi, "cookiejar": sesi})
def parse_toko(self, response):
sesi = response.meta["sesi"]
yield response.follow("?halaman=2", self.parse_toko_lanjut,
meta={"sesi": sesi, "cookiejar": sesi})

cookiejar adalah fitur bawaan Scrapy untuk memisahkan cookie. Tanpa itu, semua request di satu spider berbagi cookie yang sama, sehingga sesi berbeda tetap terlihat seperti satu pengunjung. Penjelasan lengkap soal memilih mode ada di Sticky atau rotating.

Target negara, kota, dan ISP

Targeting diatur lewat username, bukan lewat setting Scrapy. Ubah bagian -cc-ID di middleware sesuai kebutuhan:

  • -cc-SG untuk negara lain dengan kode ISO 3166-1.
  • -cc-ID-ct-Surabaya untuk kota tertentu (nama kota tanpa spasi dan tanda baca).
  • -cc-ID-isp-telkomsel atau -cc-ID-asn-7713 untuk operator jaringan tertentu.
  • -co-AS untuk satu benua.

Makin sempit target, makin sedikit IP yang tersedia. Mulai dari negara, lalu persempit hanya kalau hasilnya memang berbeda per kota atau per operator. Daftar lengkap parameter ada di dokumentasi.

Setting yang sopan dan hemat kuota

Scrapy sudah hemat secara alami: ia hanya mengunduh URL yang kamu minta, tanpa gambar, font, atau JavaScript, dan meminta respons terkompresi secara bawaan. Beberapa setting berikut membuatnya lebih sopan ke situs tujuan sekaligus menekan pemakaian GB:

Contoh
# settings.py
ROBOTSTXT_OBEY = True
CONCURRENT_REQUESTS_PER_DOMAIN = 2
DOWNLOAD_DELAY = 2
AUTOTHROTTLE_ENABLED = True
DOWNLOAD_TIMEOUT = 60
RETRY_TIMES = 2
HTTPCACHE_ENABLED = True # saat develop saja
  • ROBOTSTXT_OBEY membuat Scrapy membaca dan mematuhi robots.txt. Tetap baca juga syarat layanan situsnya.
  • CONCURRENT_REQUESTS_PER_DOMAIN, DOWNLOAD_DELAY, dan AUTOTHROTTLE_ENABLED menjaga laju request tetap wajar dan otomatis melambat saat server tujuan lambat.
  • RETRY_TIMES membatasi percobaan ulang, supaya satu error tidak berubah menjadi ratusan request yang ikut dihitung.
  • HTTPCACHE_ENABLED menyimpan respons di disk. Saat kamu mengulang spider untuk memperbaiki selector, halaman diambil dari cache dan tidak lewat proxy lagi. Matikan saat produksi kalau kamu butuh data terbaru.
Saat menulis selector, pakai scrapy shell dengan satu URL, lalu simpan responsnya. Mengulang crawl penuh hanya untuk mencoba satu selector adalah cara paling cepat menghabiskan kuota.

Kalau ada yang tidak jalan

  • 407 Proxy Authentication Required: cek ejaan username, password, dan urutan parameternya. Langkah lengkapnya ada di cara mengatasi error proxy.
  • SOCKS5 tidak jalan: Scrapy tidak mendukung SOCKS5 secara bawaan. Pakai skema http://; endpoint yang sama melayani situs HTTP maupun HTTPS.
  • 403 dari situs tujuan: artinya situs menolak request-mu. Scrapy tidak mengulang 403 secara bawaan, dan memang sebaiknya begitu. Kurangi kecepatan, cek robots.txt dan syarat layanannya, dan jangan mencoba mengakali sistem keamanan situs.
  • Timeout: turunkan DOWNLOAD_TIMEOUT (bawaannya 180 detik) supaya request yang macet cepat dilepas dan dicoba ulang.
  • Negara salah: jalankan lagi spider cekip dengan username yang sama persis dengan yang dipakai middleware.

Mulai crawl pertamamu

Satu middleware, beberapa baris setting, dan Scrapy siap memakai IP residential dari negara yang kamu pilih. Bayarnya per GB mulai Rp 10.000, minimal beli 1 GB, tanpa langganan. Cek harga, buat akun, lalu salin kredensial dari Generator proxy.