Как использовать резидентные и датацентровые прокси Smartproxy со Scrapy в Linux
Создайте промежуточное ПО загрузчика Scrapy, которое выполняет ротацию резидентных и датацентровых HTTP-прокси Smartproxy в Linux, с учетными данными из переменных окружения и повторными попытками с переключением пулов.
Обзор
Встроенный HttpProxyMiddleware в Scrapy может направлять запрос через один HTTP-прокси, но для производственного скрапинга с Smartproxy обычно нужны две вещи: пул резидентных прокси для геотаргетированных запросов или запросов, устойчивых к блокировкам, и пул датацентровых прокси для высокопроизводительных запросов. В этом руководстве показано, как добавить собственное промежуточное ПО загрузчика, которое выбирает конечную точку Smartproxy для каждого запроса, выполняет ротацию между резидентными и датацентровыми пулами и повторяет типичные ошибки прокси, не прописывая учетные данные жестко в вашем пауке.
Smartproxy поддерживает HTTP и SOCKS5; в этом руководстве используются конечные точки HTTP/HTTPS-прокси, поскольку встроенное промежуточное ПО прокси в Scrapy ожидает URL HTTP-прокси.
Предварительные требования
- Машина или контейнер Linux с Python 3.10 или новее.
- Аккаунт Smartproxy с учетными данными резидентных и/или датацентровых прокси.
- Детали конечных точек из панели управления Smartproxy: хост прокси, порт, имя пользователя и пароль для каждого пула, который вы планируете использовать.
- Доступные
pipиvenv.
Шаги
Шаг 1 — Создайте виртуальное окружение и установите Scrapy
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install scrapy python-dotenv
Шаг 2 — Сохраните учетные данные Smartproxy как переменные окружения
Не добавляйте учетные данные в репозиторий.
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'
Если вы предпочитаете файл .env, загрузите его перед запуском Scrapy. Храните файл вне системы контроля версий.
Шаг 3 — Создайте проект Scrapy
scrapy startproject smartproxy_scrapy
cd smartproxy_scrapy
scrapy genspider example example.com
Шаг 4 — Добавьте промежуточное ПО для ротации Smartproxy
Создайте smartproxy_scrapy/middlewares.py или допишите в сгенерированный файл. Промежуточное ПО устанавливает request.meta['proxy'] до запуска HttpProxyMiddleware в Scrapy.
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
Шаг 5 — Включите промежуточное ПО перед прокси-мидлварью Scrapy
Отредактируйте 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 в Scrapy имеет порядок 750, поэтому 749 гарантирует, что ваше промежуточное ПО установит URL прокси первым.
Шаг 6 — Выбирайте резидентные или датацентровые прокси для каждого запроса
Используйте meta={'proxy_pool': 'residential'} для геотаргетированных страниц или страниц с высокой анонимностью. Используйте meta={'proxy_pool': 'datacenter'} для стабильных страниц с высокой пропускной способностью.
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(),
}
Шаг 7 — Добавьте резервные повторные попытки между пулами
Код 403 или 429 от целевого сайта часто означает, что текущий IP заблокирован. Добавьте этот метод в класс SmartproxyRotationMiddleware, чтобы неудачный запрос один раз повторился с другим пулом Smartproxy.
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
Если вы используете этот резервный вариант, держите RETRY_TIMES низким, чтобы заблокированные запросы не зацикливались бесконечно.
Шаг 8 — Запустите паука и сохраните результаты
scrapy crawl smartproxy_demo -O smartproxy_results.json
Шаг 9 — Проверьте исходящий IP прокси с помощью cURL
Используйте ту же конечную точку Smartproxy HTTP вне Scrapy, чтобы подтвердить учетные данные и подключение.
curl --proxy 'http://USERNAME:PASSWORD@HOST:PORT' https://httpbin.org/ip
Замените USERNAME, PASSWORD, HOST и PORT на значения для тестируемого пула.
Устранение неполадок
407 Proxy Authentication Required: Проверьте имя пользователя и пароль, убедитесь, что они закодированы для URL, и подтвердите, что вы используете правильный хост и порт для выбранного пула.Tunnel connection failedили ошибки TLS: Убедитесь, что конечная точка Smartproxy поддерживает HTTPS-цели через HTTP CONNECT. Сначала протестируйте ее с помощью команды cURL из шага 9.- Scrapy игнорирует прокси: Убедитесь, что
SmartproxyRotationMiddlewareустановлен ниже 750 вDOWNLOADER_MIDDLEWARES, и чтоHTTPPROXY_ENABLEDимеет значениеTrue. - Частые
403или429: УменьшитеCONCURRENT_REQUESTS_PER_DOMAIN, добавьтеDOWNLOAD_DELAY, переключитесь на резидентные прокси и ротируйте user-agent только там, где это разрешено целевым сайтом. - Медленные ответы: Датацентровые прокси обычно лучше для чистой пропускной способности; резидентные прокси лучше для геотаргетированных запросов и сайтов, блокирующих диапазоны IP датацентров.
- Учетные данные содержат
@,:, или/: Оставьте вызовыurllib.parse.quoteв промежуточном ПО. Квотирование предотвращает некорректные URL прокси.
Итог
Теперь у вас есть проект Scrapy, который направляет запросы через резидентные и датацентровые HTTP-прокси Smartproxy в Linux. Промежуточное ПО выбирает пул для каждого запроса, хранит учетные данные в переменных окружения и может переключаться на другой пул, когда целевой сайт блокирует IP. Начните с низкой конкурентности, проверьте ваши исходящие IP с помощью cURL и увеличивайте CONCURRENT_REQUESTS_PER_DOMAIN только после того, как краулинг будет работать надежно.