Cara Menggunakan Proxy Residential dan Datacenter Smartproxy dengan Scrapy di Linux
Bangun middleware downloader Scrapy yang merotasi proxy HTTP residential dan datacenter Smartproxy di Linux, dengan kredensial berbasis environment dan retry fallback antar pool.
Ringkasan
HttpProxyMiddleware bawaan Scrapy dapat merutekan permintaan melalui satu proxy HTTP, tetapi scraping produksi dengan Smartproxy biasanya membutuhkan dua hal: pool residential untuk permintaan yang ditargetkan secara geografis atau tahan blokir, dan pool datacenter untuk permintaan dengan throughput tinggi. Tutorial ini menunjukkan cara menambahkan middleware downloader kustom yang memilih endpoint Smartproxy per permintaan, merotasi antara pool residential dan datacenter, serta mencoba ulang error proxy umum tanpa meng-hard-code kredensial di spider Anda.
Smartproxy mendukung HTTP dan SOCKS5; panduan ini menggunakan endpoint proxy HTTP/HTTPS karena middleware proxy bawaan Scrapy mengharapkan URL proxy HTTP.
Prasyarat
- Mesin atau container Linux dengan Python 3.10 atau lebih baru.
- Akun Smartproxy dengan kredensial proxy residential dan/atau datacenter.
- Detail endpoint dari dashboard Smartproxy: host proxy, port, username, dan password untuk setiap pool yang akan Anda gunakan.
pipdanvenvtersedia.
Langkah-langkah
Langkah 1 — Buat virtual environment dan instal Scrapy
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install scrapy python-dotenv
Langkah 2 — Simpan kredensial Smartproxy sebagai variabel environment
Jangan commit kredensial ke repositori Anda.
export SMARTPROXY_RES_HOST='your-residential-host'
export SMARTPROXY_RES_PORT='your-residential-port'
export SMARTPROXY_RES_USERNAME='your-residential-username'
export SMARTPROXY_RES_PASSWORD='your-residential-password'
export SMARTPROXY_DC_HOST='your-datacenter-host'
export SMARTPROXY_DC_PORT='your-datacenter-port'
export SMARTPROXY_DC_USERNAME='your-datacenter-username'
export SMARTPROXY_DC_PASSWORD='your-datacenter-password'
Jika Anda lebih suka file .env, muat file itu sebelum Scrapy dimulai. Jauhkan file tersebut dari kontrol versi.
Langkah 3 — Buat proyek Scrapy
scrapy startproject smartproxy_scrapy
cd smartproxy_scrapy
scrapy genspider example example.com
Langkah 4 — Tambahkan middleware rotasi Smartproxy
Buat smartproxy_scrapy/middlewares.py atau tambahkan ke file yang dihasilkan. Middleware menetapkan request.meta['proxy'] sebelum HttpProxyMiddleware Scrapy berjalan.
import os
from urllib.parse import quote
from scrapy import signals
from scrapy.exceptions import NotConfigured
from scrapy.utils.project import get_project_settings
class SmartproxyRotationMiddleware:
'''Route Scrapy requests through Smartproxy residential or datacenter endpoints.'''
def __init__(self, settings):
self.pools = {
'residential': {
'host': settings.get('SMARTPROXY_RES_HOST'),
'port': settings.get('SMARTPROXY_RES_PORT'),
'username': settings.get('SMARTPROXY_RES_USERNAME'),
'password': settings.get('SMARTPROXY_RES_PASSWORD'),
},
'datacenter': {
'host': settings.get('SMARTPROXY_DC_HOST'),
'port': settings.get('SMARTPROXY_DC_PORT'),
'username': settings.get('SMARTPROXY_DC_USERNAME'),
'password': settings.get('SMARTPROXY_DC_PASSWORD'),
},
}
if not any(pool['host'] and pool['port'] for pool in self.pools.values()):
raise NotConfigured('Set at least one Smartproxy pool host and port.')
@classmethod
def from_crawler(cls, crawler):
middleware = cls(crawler.settings)
crawler.signals.connect(middleware.spider_opened, signal=signals.spider_opened)
return middleware
def spider_opened(self, spider):
spider.logger.info('Smartproxy rotation middleware enabled')
def process_request(self, request, spider):
pool_name = request.meta.get('proxy_pool', 'residential')
pool = self.pools.get(pool_name)
if not pool or not pool['host'] or not pool['port']:
return None
host = pool['host']
port = pool['port']
username = quote(pool['username'] or '', safe='')
password = quote(pool['password'] or '', safe='')
if username and password:
proxy_url = f'http://{username}:{password}@{host}:{port}'
else:
proxy_url = f'http://{host}:{port}'
request.meta['proxy'] = proxy_url
request.meta['smartproxy_pool'] = pool_name
return None
Langkah 5 — Aktifkan middleware sebelum middleware proxy Scrapy
Edit smartproxy_scrapy/settings.py.
DOWNLOADER_MIDDLEWARES = {
'smartproxy_scrapy.middlewares.SmartproxyRotationMiddleware': 749,
}
HTTPPROXY_ENABLED = True
DOWNLOAD_TIMEOUT = 30
RETRY_HTTP_CODES = [403, 407, 429, 500, 502, 503, 504]
RETRY_TIMES = 2
CONCURRENT_REQUESTS = 16
CONCURRENT_REQUESTS_PER_DOMAIN = 4
HttpProxyMiddleware bawaan Scrapy diurutkan pada 750, jadi 749 memastikan middleware Anda menetapkan URL proxy terlebih dahulu.
Langkah 6 — Pilih residential atau datacenter per permintaan
Gunakan meta={'proxy_pool': 'residential'} untuk halaman yang ditargetkan secara geografis atau beranonimitas tinggi. Gunakan meta={'proxy_pool': 'datacenter'} untuk halaman yang stabil dengan throughput tinggi.
import scrapy
class SmartproxyDemoSpider(scrapy.Spider):
name = 'smartproxy_demo'
start_urls = ['https://httpbin.org/ip']
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(
url,
meta={'proxy_pool': 'residential'},
callback=self.parse,
dont_filter=True,
)
yield scrapy.Request(
url,
meta={'proxy_pool': 'datacenter'},
callback=self.parse,
dont_filter=True,
)
def parse(self, response):
yield {
'pool': response.meta.get('smartproxy_pool'),
'status': response.status,
'origin': response.text.strip(),
}
Langkah 7 — Tambahkan retry fallback antar pool
403 atau 429 dari situs target sering berarti IP saat ini diblokir. Tambahkan metode ini di dalam kelas SmartproxyRotationMiddleware agar permintaan yang gagal dicoba ulang sekali dengan pool Smartproxy lainnya.
def process_response(self, request, response, spider):
retryable = {403, 429}
already_switched = request.meta.get('smartproxy_pool_retry', False)
if response.status in retryable and not already_switched:
current = request.meta.get('proxy_pool', 'residential')
alternate = 'datacenter' if current == 'residential' else 'residential'
new_meta = request.meta.copy()
new_meta['proxy_pool'] = alternate
new_meta['smartproxy_pool_retry'] = True
spider.logger.warning(
'Retrying %s with %s pool after HTTP %s',
request.url,
alternate,
response.status,
)
return request.replace(meta=new_meta, dont_filter=True)
return response
Jika Anda menggunakan fallback ini, jaga RETRY_TIMES tetap rendah agar permintaan yang diblokir tidak berulang tanpa henti.
Langkah 8 — Jalankan spider dan simpan hasil
scrapy crawl smartproxy_demo -O smartproxy_results.json
Langkah 9 — Verifikasi IP keluar proxy dengan cURL
Gunakan endpoint HTTP Smartproxy yang sama di luar Scrapy untuk mengonfirmasi kredensial dan konektivitas.
curl --proxy 'http://USERNAME:PASSWORD@HOST:PORT' https://httpbin.org/ip
Ganti USERNAME, PASSWORD, HOST, dan PORT dengan nilai untuk pool yang Anda uji.
Pemecahan Masalah
407 Proxy Authentication Required: Periksa username dan password, pastikan keduanya di-encode URL, dan konfirmasi bahwa Anda menggunakan host dan port yang benar untuk pool yang dipilih.Tunnel connection failedatau error TLS: Konfirmasi bahwa endpoint Smartproxy mendukung target HTTPS melalui HTTP CONNECT. Uji terlebih dahulu dengan perintah cURL di Langkah 9.- Scrapy mengabaikan proxy: Konfirmasi bahwa
SmartproxyRotationMiddlewarediatur di bawah 750 dalamDOWNLOADER_MIDDLEWARES, dan bahwaHTTPPROXY_ENABLEDbernilaiTrue. - Sering
403atau429: TurunkanCONCURRENT_REQUESTS_PER_DOMAIN, tambahkanDOWNLOAD_DELAY, beralih ke proxy residential, dan rotasi user agent hanya jika target mengizinkannya. - Respons lambat: Proxy datacenter biasanya lebih baik untuk throughput mentah; proxy residential lebih baik untuk permintaan yang ditargetkan secara geografis dan situs yang memblokir rentang IP datacenter.
- Kredensial berisi
@,:, atau/: Pertahankan pemanggilanurllib.parse.quotedi middleware. Pengodean ini mencegah URL proxy yang rusak.
Ringkasan
Anda sekarang memiliki proyek Scrapy yang merutekan permintaan melalui proxy HTTP residential dan datacenter Smartproxy di Linux. Middleware memilih pool per permintaan, menyimpan kredensial dalam variabel environment, dan dapat beralih ke pool lain saat target memblokir IP. Mulailah dengan konkurensi rendah, verifikasi IP keluar Anda dengan cURL, dan tingkatkan CONCURRENT_REQUESTS_PER_DOMAIN hanya setelah crawl berjalan dengan andal.