Skip to content
Advanced / 6 min read

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.

Linux HTTP(S) Web Scraping

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.
  • pip dan venv tersedia.

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 failed atau 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 SmartproxyRotationMiddleware diatur di bawah 750 dalam DOWNLOADER_MIDDLEWARES, dan bahwa HTTPPROXY_ENABLED bernilai True.
  • Sering 403 atau 429: Turunkan CONCURRENT_REQUESTS_PER_DOMAIN, tambahkan DOWNLOAD_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 pemanggilan urllib.parse.quote di 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.