Гайд по Scrapy · 1 мин чтения

Как использовать прокси в Scrapy

Scrapy пускает запросы через прокси тремя способами: ключ meta на запрос, переменная окружения или ротационный downloader middleware. Разбираем каждый, с рабочим кодом для прокси s4m с аутентификацией.

Три способа, которыми Scrapy общается с прокси

Scrapy поставляется с HttpProxyMiddleware, включённым по умолчанию. Он берёт прокси из одного из двух мест: ключа proxy в словаре meta запроса или стандартных переменных окружения http_proxy / https_proxy. Если нужен один фиксированный прокси на весь обход, быстрее всего — переменная окружения; если же нужны управление и ротация на уровне запроса, выставляйте request.meta["proxy"] сами, обычно из собственного downloader-мидлваря.

Аутентификация — ровно то, что обычно упускают. Scrapy не вытаскивает USER:PASS@ из URL прокси так, как это делает curl, — он ждёт заголовок Proxy-Authorization. Чистый подход — собрать этот заголовок один раз и добавлять его в своём мидлваре. Прокси s4m аутентифицируются парой USER:PASS на proxy.s4m.online, HTTP — на порту 3128 (естественный вариант для HTTP-мидлваря Scrapy). Для SOCKS5 пришлось бы поставить перед обходом локальный мост SOCKS-в-HTTP, но для большинства скрапинга проще взять HTTP-эндпоинт. Подробнее — на странице прокси, а также в других руководствах по скрапингу.

Мидлварь с ротацией прокси

Положите это в middlewares.py, включите в settings.py — и каждый запрос будет брать прокси из вашего пула вместе с правильным заголовком аутентификации.

python
# middlewares.py
import base64
import random

USER, PASS, HOST = "USER", "PASS", "proxy.s4m.online"
PROXIES = [f"http://{HOST}:3128"]  # add more endpoints/ports to rotate

class S4mProxyMiddleware:
    def _auth_header(self):
        raw = f"{USER}:{PASS}".encode()
        return b"Basic " + base64.b64encode(raw)

    def process_request(self, request, spider):
        request.meta["proxy"] = random.choice(PROXIES)
        # Scrapy needs the Proxy-Authorization header explicitly:
        request.headers[b"Proxy-Authorization"] = self._auth_header()

# settings.py
DOWNLOADER_MIDDLEWARES = {
    # keep Scrapy's built-in proxy middleware after ours
    "myproject.middlewares.S4mProxyMiddleware": 350,
    "scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": 400,
}
CONCURRENT_REQUESTS = 8
DOWNLOAD_DELAY = 0.5
RETRY_ENABLED = True
RETRY_TIMES = 3
RETRY_HTTP_CODES = [429, 500, 502, 503, 504]

Собираем всё вместе

От чистого проекта до обхода через прокси.

Добавьте мидлварь

Вставьте класс S4mProxyMiddleware в middlewares.py своего проекта и замените USER, PASS и HOST на свои учётные данные и эндпоинт s4m.

Включите его в настройках

Зарегистрируйте его в DOWNLOADER_MIDDLEWARES с приоритетом ниже, чем у HttpProxyMiddleware из Scrapy (меньшее число срабатывает раньше), чтобы ваш прокси и заголовок были выставлены до запуска встроенного мидлваря.

Настройте вежливость

Выставьте DOWNLOAD_DELAY и CONCURRENT_REQUESTS так, чтобы не упираться в лимит скорости цели, и включите RETRY_HTTP_CODES для 429 и 5xx — тогда временные блокировки будут повторяться автоматически.

Проверьте выходной IP

Добавьте первый запрос к сервису, возвращающему IP, например https://api.ipify.org, и залогируйте ответ — так вы убедитесь, что обход действительно выходит через прокси.

Ротация, повторы и честность

Для настоящей ротации положите несколько эндпоинтов в PROXIES и пусть process_request выбирает по одному на запрос; соедините это со встроенным мидлварем повторов Scrapy, чтобы 429 или 503 повторялись уже с новым выбором. Держите DOWNLOAD_DELAY ненулевым, а параллельность — умеренной: краулер, который отступает, заблокировать намного труднее, чем того, кто бежит спринт.

Две честные оговорки. Первая: прокси s4m — серверные, а не резидентские: отличны для API, тестирования и умеренно защищённых сайтов, но агрессивные антибот-системы могут помечать серверные диапазоны. Вторая: ротация не даёт права игнорировать правила сайта — читайте robots.txt и условия использования. Когда нужен один постоянный выход для белого списка, лучше возьмите выделенный персональный IP, а не ротацию. Проверяйте выходы и порты в инструментах, а прототипируйте на бесплатном списке прокси, прежде чем пускать настоящий трафик.

FAQ

Ответы на вопросы

Почему Scrapy не берёт USER:PASS из URL прокси?

В отличие от curl, HttpProxyMiddleware в Scrapy не разбирает учётные данные из URL. Заголовок Proxy-Authorization нужно выставить самому — собрать Basic-заголовок из USER:PASS, как показано в примере мидлваря.

Может ли Scrapy работать с прокси SOCKS5?

Не напрямую через HttpProxyMiddleware — он ориентирован на HTTP. Для Scrapy используйте HTTP-эндпоинт на порту 3128 или поднимите локальный мост SOCKS-в-HTTP, если SOCKS5 нужен принципиально.

Как ротировать прокси на каждый запрос?

Сложите несколько эндпоинтов прокси в список и выбирайте один в process_request, каждый раз выставляя request.meta["proxy"]. Соедините это с мидлварем повторов Scrapy, чтобы заблокированный запрос повторялся уже с новым выбором.

Это резидентные прокси?

Нет. Прокси s4m — это серверные SOCKS5 и HTTP с аутентификацией и оплатой по факту использования. Они подходят для большинства задач скрапинга, хотя хорошо защищённые цели могут помечать серверные диапазоны IP.

Масштабируйте свои обходы на Scrapy

Серверные прокси с аутентификацией на proxy.s4m.online, оплата по факту использования, готовые к ротации в мидлвари Scrapy. Добавьте выделенный IP, когда цель ожидает один постоянный выход.

Эту страницу нашли по запросу

Реальные поисковые фразы, на которые отвечает эта страница — по ссылкам откроются материалы, раскрывающие тему глубже.