GeekProxy в Scrapy

В settings.py у Scrapy нет поля для прокси, и в первый день это сбивает с толку. Есть middleware, которая читает URL прокси из каждого запроса, и обычные переменные окружения. В гайде оба пути, судьба вашего пароля внутри middleware, SOCKS5 через httpx-обработчик и sticky-сессии на одном шлюзе.

Что нужно: активный план GeekProxy и данные прокси из кабинета. Первый краул через прокси занимает минут пять.

Получить прокси

1 Перед началом

Вся поддержка прокси в Scrapy живёт в одной downloader middleware, HttpProxyMiddleware. Она включена по умолчанию с порядком 750 в DOWNLOADER_MIDDLEWARES_BASE, ставить ничего не надо. Её работа, по документации: выставить HTTP-прокси запросу, прочитав meta-значение proxy. Управляют ею две настройки: HTTPPROXY_ENABLED (по умолчанию True) и HTTPPROXY_AUTH_ENCODING (по умолчанию "latin-1").

Это всё. На весь проект прокси задаётся переменными окружения, на запрос через meta['proxy'], а соединить одно с другим может middleware на десять строк.

  • Формат URL прокси: scheme://[user:pass@]host:port. Строки вида host:port:user:pass Scrapy не разбирает
  • Нормальная схема http://. Прокси https:// работает только с целями http://, а с версии 2.16.0 стандартный обработчик бросает исключение, когда и цель, и прокси https://. Порты GeekProxy обычные HTTP-прокси, так что берём http://
  • SOCKS5 требует httpx-обработчик. Вердикт в разделе 5
  • Через прокси идут только загрузки паука. Экспорт фидов, Telnet-консоль и Scrapyd не затронуты, если сами не читают те же переменные

Что понадобится

  • Активный план GeekProxy (резидентские, ISP или датацентр)
  • Данные прокси из кабинета: хост, порт, логин, пароль
  • Python 3 с установленным Scrapy. Для httpx-обработчика нужен Scrapy 2.17 или новее
Ваши данные доступа
  • Поле Откуда взять
  • Протокол HTTP (SOCKS5 только через httpx-обработчик)
  • Хост IP или имя шлюза из кабинета
  • Порт из кабинета
  • Логин из кабинета
  • Пароль из кабинета

2 Где взять данные прокси

  1. Войдите в кабинет GeekProxy
  2. Откройте план. У планов с оплатой за IP (датацентр, ISP) список адресов, порты, логин и пароль лежат прямо на карточке, а кнопка Export отдаёт весь список текстом
  3. У резидентских и мобильных планов нажмите Options. Панель Proxy Configuration соберёт строку логина с вашей страной, городом и настройками сессии. Готовую строку копируйте из Proxy List

Краулеру настройки сессии важнее страны. На Residential Turbo в логине живут session_id и session_time (от 1 до 1440 минут), на Residential Flex session_time до 120 минут и фильтр выхода вроде -os-windows.

Кабинет GeekProxy, Subscriptions
Кабинет GeekProxy, страница Subscriptions: планы ISP со ссылкой Export, планы Residential Flex и Turbo с кнопками Options и Add GB
Кабинет GeekProxy, Residential Flex
Подписка Residential Flex, панель Proxy Configuration: континент, ASN, ZIP, регион, ОС устройства, тип прокси и TTL сессии, ниже готовая строка curl

3 Весь проект: переменные окружения

Как и urllib.request из стандартной библиотеки, middleware слушается http_proxy, https_proxy и no_proxy. Экспортируйте их в той оболочке, где запускаете краул, и каждый запрос каждого паука пойдёт через прокси. Логин и пароль внутри переменной разбирает та же функция, что и meta['proxy'], так что форма URL та же.

export https_proxy="http://LOGIN:PASSWORD@IP:PORT"
export http_proxy="http://LOGIN:PASSWORD@IP:PORT"
scrapy crawl ip

Задавайте обе. Переменная выбирается по схеме целевого URL, а краул, начавшийся на https://, вполне может уйти редиректом на http://. no_proxy выводит хост из-под прокси, это полезно, когда паук заодно ходит в ваш собственный API.

Терминал, scrapy crawl через переменные окружения
Терминал: экспорт https_proxy и http_proxy с URL GeekProxy, затем scrapy crawl ip

Переменные окружения это единственный общепроектный переключатель, который есть в Scrapy. Хотите выбирать прокси в коде? Маленькая downloader middleware, которая заполняет request.meta['proxy'] раньше порядка 750, решает вопрос. Пример в разделе 4.

4 На запрос: meta-ключ proxy

Поставьте запросу meta-ключ proxy со значением http://IP:PORT или http://LOGIN:PASSWORD@IP:PORT. Документация добавляет два предупреждения. Это значение важнее http_proxy и https_proxy, и оно полностью игнорирует no_proxy. Паук, который проверяет свой выходной IP, выглядит так.

import scrapy

class IpSpider(scrapy.Spider):
    name = "ip"

    def start_requests(self):
        yield scrapy.Request(
            "https://ipinfo.io/json",
            meta={"proxy": "http://LOGIN:PASSWORD@IP:PORT"},
        )

    def parse(self, response):
        self.logger.info(response.text)

meta={"proxy": None} делает обратное: выключает прокси для этого одного запроса, даже если переменные окружения заданы.

ip_spider.py
Редактор: паук Scrapy с meta-ключом proxy, в котором URL GeekProxy

Один прокси на все запросы, из кода

Официального сниппета для этого в Scrapy нет. Код ниже выведен из двух задокументированных фактов: meta-ключа proxy и порядка 750 у встроенной middleware. Всё, что отработает раньше и заполнит ключ, побеждает.

# middlewares.py
class GeekProxyMiddleware:
    def process_request(self, request, spider):
        request.meta.setdefault("proxy", "http://LOGIN:PASSWORD@IP:PORT")

# settings.py
DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.GeekProxyMiddleware": 700,
}
HTTPPROXY_AUTH_ENCODING = "utf-8"

Что происходит с паролем

Документация говорит лишь, что логин и пароль можно вписать в URL. Точные правила лежат в исходнике middleware, и спотыкаются о них чаще, чем кажется. Middleware раскодирует percent-encoding в userinfo, кодирует его в HTTPPROXY_AUTH_ENCODING и пишет заголовок Proxy-Authorization: Basic. Потом вырезает логин и пароль из meta['proxy'] и запоминает, какому URL прокси принадлежит заголовок.

Отсюда три следствия. Код, который позже читает response.meta['proxy'], видит URL без логина. Повтор или редирект на тот же прокси сохраняет заголовок. Запрос на другой URL прокси без логина заголовок теряет: middleware удаляет устаревший. Поэтому при смене прокси на каждый item передавайте логин и пароль заново. Каждый раз.

Кодировка по умолчанию latin-1. Паролю с нелатинскими символами нужна строка HTTPPROXY_AUTH_ENCODING = "utf-8" в settings.py. Спецсимволы вроде @ или : внутри URL кодируются процентами, middleware раскодирует их перед сборкой заголовка.

5 SOCKS5, ротация и sticky-сессии

SOCKS5 с логином и паролем в Scrapy работает, но с оговоркой: SOCKS понимает только httpx-обработчик загрузок. Стандартный обработчик на Twisted не умеет, а обработчик HTTP/2 вообще не трогает meta-ключ proxy. Scrapy 2.17.0 (июль 2026) добавил SOCKS и HTTP/2 в HttpxDownloadHandler; 2.19.0 (сентябрь 2026) перенёс его на httpx2, ставится через pip install scrapy[httpx]. Переключение делается в DOWNLOAD_HANDLERS: ключи http и https указывают на класс обработчика. Путь к классу берите из справочника API вашей версии, между релизами он переезжал.

С этим обработчиком URL вида socks5://LOGIN:PASSWORD@IP:PORT принимается. Уважает ли Scrapy форму socks5h:// (DNS на стороне прокси), мы не проверяли. У HTTP-прокси такого вопроса нет: CONNECT несёт имя хоста. Наш совет: оставайтесь на http://, пока что-то конкретное не потянет в SOCKS.

Один ротируемый шлюз

Логин Turbo или Flex ротирует сам. Каждое новое TCP-соединение может выйти с нового адреса, в этом весь фокус. Scrapy держит соединения живыми на хост, поэтому серия запросов к одному сайту может делить один выход, пока соединение не закроется. Так и задумано. Нужен один IP на логическую сессию, скажем на аккаунт? Кладите логин Turbo с session_id или Flex с session_time в meta['proxy'] каждого запроса этого item. И помните, что CONCURRENT_REQUESTS_PER_DOMAIN считает целевой домен, а не прокси.

Список статических IP

План датацентра или ISP выдаёт список, а списку нужен ротатор. Сторонний пакет scrapy-rotating-proxies читает ROTATING_PROXY_LIST или ROTATING_PROXY_LIST_PATH; если заданы оба, файл важнее. Записи могут содержать логин и пароль, в README есть формы login:password@host:port. Правило бана по умолчанию: статус не 200, пустое тело или исключение. Переопределяется через ROTATING_PROXY_BAN_POLICY либо методами паука response_is_ban и exception_is_ban.

# settings.py, pip install scrapy-rotating-proxies
ROTATING_PROXY_LIST = [
    "http://LOGIN:PASSWORD@IP:PORT",
    "http://LOGIN:PASSWORD@IP:PORT",
]

DOWNLOADER_MIDDLEWARES = {
    "rotating_proxies.middlewares.RotatingProxyMiddleware": 610,
    "rotating_proxies.middlewares.BanDetectionMiddleware": 620,
}

Пакет рассчитан на разные прокси. Только планы с оплатой за IP, не один ротируемый шлюз.

settings.py, scrapy-rotating-proxies
Редактор: settings.py с ROTATING_PROXY_LIST и двумя middleware пакета rotating-proxies

6 Проверка работы

Запустите scrapy crawl ip с пауком из раздела 4. В логе появится JSON с https://ipinfo.io/json, и поле ip должно показать адрес прокси, а не ваш. На ISP или датацентре это адрес из кабинета, на Residential или Turbo любой адрес из пула в выбранной стране.

Вторая проверка дешевле, чем звучит. Залогируйте response.meta['proxy'] внутри parse. URL прокси без логина значит, что middleware отработала и собрала заголовок. Пароль на месте значит, что middleware выключена или стоит после вашей.

7 Какой продукт GeekProxy подходит

Краулу в объёме нужна широта, поэтому Residential Turbo в ротации по HTTP или Residential Flex в ротации: он работает только по TCP, краулеру этого хватает. У Flex есть фильтр выхода -os-windows для целей, которые смотрят на TCP-отпечаток. Сайтам, которые привязывают куки к адресу, нужен sticky-логин на item, как в разделе 5. Опрос пары API дешевле на датацентре IPv4 или статическом ISP: короткий список в ROTATING_PROXY_LIST, счётчика трафика нет. Во всех случаях берите HTTP-строки. Мобильные нужны целям, которые требуют именно операторскую сеть.

8 Частые проблемы

407 Proxy Authentication Required после смены прокси на запросе

Новый meta['proxy'] указывает на другой URL без логина, и middleware сняла старый заголовок. Пишите LOGIN:PASSWORD@ в каждый URL прокси, который задаёте, включая повторы, собранные руками.

Прокси из окружения игнорируется для части запросов

У этих запросов есть meta['proxy'], а он всегда важнее. Заодно поищите meta={"proxy": None}: он выключает прокси у запроса намеренно.

Запрос к localhost уходит через прокси

meta['proxy'] игнорирует no_proxy. Поставьте локальному запросу meta={"proxy": None}.

Пароль неверный, хотя он верный

Нелатинские символы по умолчанию кодируются в latin-1. Задайте HTTPPROXY_AUTH_ENCODING = "utf-8". Пароль с @, : или # внутри URL кодируется процентами.

URL socks5:// не работает со стандартным обработчиком

SOCKS поддерживает только httpx-обработчик. Поставьте scrapy[httpx] и переключите DOWNLOAD_HANDLERS либо возьмите HTTP-порт того же плана.

Не получается? Напишите нам в Telegram, Discord или в чат на сайте. Обычно отвечаем в течение нескольких минут.

Прокси для Scrapy

Ротируемые резидентские по гигабайтам или статические ISP и датацентр без счётчика трафика, выдача за секунды.

Заказать

We use cookies to improve user experience. By clicking "Yes, I agree", you consent to this use of cookies.

Привилегия первых: В честь глобального запуска [мы даем скидку 50%+] на все датацентр тарифы. Эксклюзивное предложение для наших стартовых партнеров.