NP NEONPROXYPROXY NETWORK
КупитьЦеныFAQПартнёркаБлог Прокси-чекерМой IPAPI TG-бот

Прокси в Scrapy: middleware и ротация

Scrapy — асинхронный фреймворк для краулинга на Python. Он масштабируется на тысячи запросов в минуту и имеет встроенную поддержку прокси через middleware. Пул адресов NEONPROXY снижает блокировки при сборе публичных данных — цен, каталогов, SEO-метрик. Ниже — настройка HttpProxyMiddleware, кастомная ротация и обработка ошибок. Соблюдайте robots.txt и Terms of Service целевых сайтов.

Встроенный HttpProxyMiddleware

Самый простой способ — указать один прокси в settings.py с авторизацией в URL:

# settings.py
DOWNLOADER_MIDDLEWARES = {
    "scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": 750,
}

PROXY = "http://login:password@123.45.67.89:8080"

В spider переопределите метод, добавляющий meta:

class MySpider(scrapy.Spider):
    name = "example"

    def start_requests(self):
        for url in self.start_urls:
            yield scrapy.Request(
                url,
                meta={"proxy": self.settings.get("PROXY")},
                callback=self.parse
            )
SVYAZVPN — свобода без границ

Ротация через middleware

Для пула прокси создайте кастомный middleware — round-robin на каждый request:

import random
from scrapy.exceptions import NotConfigured

class RotatingProxyMiddleware:
    def __init__(self, proxies, user, password):
        self.proxies = proxies
        self.auth = f"{user}:{password}@"
        self.index = 0

    @classmethod
    def from_crawler(cls, crawler):
        proxies = crawler.settings.getlist("ROTATING_PROXIES")
        user = crawler.settings.get("PROXY_USER")
        password = crawler.settings.get("PROXY_PASS")
        if not proxies:
            raise NotConfigured
        return cls(proxies, user, password)

    def process_request(self, request, spider):
        host = self.proxies[self.index % len(self.proxies)]
        self.index += 1
        request.meta["proxy"] = f"http://{self.auth}{host}"
        request.meta["proxy_host"] = host

Регистрация в settings:

DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.RotatingProxyMiddleware": 350,
    "scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": 750,
}

ROTATING_PROXIES = ["1.2.3.4:8080", "5.6.7.8:8080", "9.10.11.12:8080"]
PROXY_USER = "login"
PROXY_PASS = "password"

Стратегии sticky vs round-robin — в гайде по ротации.

Обработка 403 и 429

Помечайте «холодные» прокси и повторяйте запрос с другим IP:

from scrapy.downloadermiddlewares.retry import RetryMiddleware

class ProxyRetryMiddleware(RetryMiddleware):
    def process_response(self, request, response, spider):
        if response.status in (403, 429, 502, 503):
            host = request.meta.get("proxy_host")
            spider.crawler.engine.slot.scheduler.df.cold_proxies.add(host)
            reason = f"proxy_banned_{response.status}"
            return self._retry(request, reason, spider) or response
        return response

Задайте RETRY_TIMES = 3 и DOWNLOAD_DELAY = 1 — уважайте лимиты сайта.

SOCKS5 в Scrapy

Стандартный HttpProxyMiddleware работает с HTTP-прокси. Для SOCKS5 установите scrapy-socks или используйте HTTP-режим NEONPROXY на том же порту — оба протокола доступны на одном заказе, см. SOCKS5 vs HTTPS.

Загрузка пула из API

При старте проекта подгружайте список из API NEONPROXY:

import requests

def load_proxies(api_key):
    r = requests.get(
        "https://svyaz.mom/api/v2/proxy/list",
        headers={"Authorization": f"Bearer {api_key}"}
    )
    return [f"{p['ip']}:{p['port_http']}" for p in r.json()["data"]]

Для IPv6-пулов при парсинге открытых сайтов см. IPv6 vs IPv4.

Отладка и метрики

Перед добавлением в пул проверяйте адреса в чекере. Логируйте success rate по каждому IP в spider stats. Для JS-страниц Scrapy не подходит — используйте Playwright или Puppeteer. Простые запросы — requests.

Выбор типа прокси

Массовый краулинг публичных каталогов — IPv6 или shared IPv4 с ротацией. Редкие запросы к чувствительным площадкам — приватный IPv4. Критерии — как выбрать прокси. Заказ — NEONPROXY.