GeekProxy в Python requests и curl

Два инструмента закрывают почти все скрипты: curl для быстрой проверки из терминала, requests для всего, что крутится по расписанию. Оба принимают прокси как URL, и оба неправильно решают DNS через SOCKS5, пока вы не скажете им иначе.

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

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

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

Оба инструмента общаются с прокси одинаково. Вы даёте им URL прокси, они открывают CONNECT-туннель для HTTPS-целей или пересылают обычные HTTP-запросы, а сайт видит IP прокси. Остальные программы на машине это не затрагивает.

  • Формат URL прокси: scheme://user:password@host:port. Схема http:// для HTTP-прокси, socks5:// или socks5h:// для SOCKS5
  • Если план GeekProxy переключён на белый список IP, часть user:password@ просто убираем
  • Спецсимволы в пароле кодируются как в URL: @ превращается в %40, двоеточие в %3a

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

  • Активный план GeekProxy (датацентр, ISP или резидентские)
  • Данные прокси из кабинета: хост, порт, логин, пароль
  • curl 7.21 или новее (есть в macOS и почти любом Linux, в Windows 10 и 11 тоже), Python 3.8 или новее с установленным requests
Ваши данные доступа
  • Поле Откуда взять
  • Протокол HTTP / SOCKS5
  • Хост IP или имя шлюза из кабинета
  • Порт из кабинета
  • Логин из кабинета
  • Пароль из кабинета

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

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

Скриптам, которые работают без человека, копировать руками не обязательно. API GeekProxy отдаёт тот же список прокси в JSON, подробности в гайде по автоматизации.

Кабинет GeekProxy, Subscriptions
Кабинет GeekProxy, страница Subscriptions: планы ISP со ссылкой Export, планы Residential Flex и Turbo с кнопками Options и Add GB

3 curl

Хватает одного флага: -x (длинная форма --proxy). После него полный URL прокси, и запрос уходит через туннель.

curl -x http://LOGIN:PASSWORD@IP:PORT https://ipinfo.io/json

В ответ приходит короткий JSON с IP, который видит сайт. Совпал с прокси, значит всё работает. Три детали из мануала curl, которые стоит знать до того, как строить на этом что-то серьёзное:

  • Без схемы строка прокси считается HTTP-прокси. Без порта подставляется 1080, а не 8080 и не 3128
  • Логин и пароль можно вынести из URL: -U LOGIN:PASSWORD (длинная форма --proxy-user). Удобно, когда в пароле странные символы
  • Аргументы командной строки видны другим пользователям той же машины через список процессов. На общем сервере лучше переменная окружения, о ней ниже
Терминал, curl через ISP-адрес GeekProxy
Терминал: curl без прокси показывает домашний IP, curl с -x показывает IP прокси, ipinfo.io подтверждает город и сеть прокси

Таймауты

По умолчанию curl ждёт бесконечно. В каждый скриптовый вызов добавляйте два флага: --connect-timeout 10 ограничивает фазу соединения (DNS, TCP, TLS), --max-time 60 ограничивает весь запрос целиком. С неверным портом вы получите код выхода 28 через десять секунд, а не зависший cron.

curl --proxy IP:PORT --proxy-user LOGIN:PASSWORD \
     --connect-timeout 10 --max-time 60 https://ipinfo.io/json

Переменные окружения

Задайте https_proxy один раз, и каждый вызов curl в этой оболочке пойдёт через прокси. Те же переменные читают requests, pip, git и большинство других утилит, так что это самый короткий способ пустить через прокси целый скрипт, не трогая его код.

export https_proxy="http://LOGIN:PASSWORD@IP:PORT"
export http_proxy="http://LOGIN:PASSWORD@IP:PORT"
curl https://ipinfo.io/json

Две особенности из мануала. Переменные в нижнем регистре важнее, чем в верхнем, а http_proxy существует только в нижнем. И загляните в ~/.curlrc: забытая строка proxy = там молча применяется к каждому вызову.

4 Python requests

requests принимает словарь proxies с записью на каждую схему. Передавайте его в каждый вызов. И всегда ставьте таймаут: по умолчанию его нет, и подвисшее соединение может держать скрипт минутами.

import requests

PROXY = "http://LOGIN:PASSWORD@IP:PORT"
proxies = {"http": PROXY, "https": PROXY}

r = requests.get("https://ipinfo.io/json", proxies=proxies, timeout=(5, 30))
print(r.json())        # {'ip': 'x.x.x.x', 'city': 'Manila', 'region': 'National Capital Region', 'country': 'PH', 'org': 'AS395793 Arisk Communications inc.', ...}

Кортеж (5, 30) значит пять секунд на соединение и тридцать на чтение. В документации отдельно сказано, что таймаут соединения считается на каждый IP-адрес, так что хост с записями IPv4 и IPv6 может ждать вдвое дольше, прежде чем сдаться.

Сессии и одна ловушка

requests.Session держит TCP-соединение открытым между вызовами. Это быстрее, а на ротируемом плане ещё и сохраняет один выходной IP, пока живёт соединение. Ловушка в другом: session.proxies перебивается прокси из окружения. Официальная документация говорит об этом прямым текстом. Если где-то задан https_proxy, настройка сессии проигрывает. Передавайте proxies= в каждый запрос или создавайте сессию с trust_env = False.

s = requests.Session()
s.trust_env = False            # не читать http_proxy / https_proxy из окружения
s.proxies.update(proxies)

for url in urls:
    r = s.get(url, timeout=(5, 30))

requests тоже читает http_proxy, https_proxy, all_proxy и no_proxy из окружения, в любом регистре. Для разового скрипта это самый короткий путь: экспортировать переменную и вызвать requests.get() вообще без аргумента proxies.

5 SOCKS5 и DNS

Для SOCKS5 нужен один дополнительный пакет: pip install "requests[socks]". Потом меняем схему. И вот здесь большинство теряет час.

  • socks5:// резолвит имя целевого сайта на вашей машине и отправляет прокси уже IP. Ваш DNS-провайдер видит каждый домен, а сайт с гео-балансировкой может выдать адрес, который не подходит под страну прокси
  • socks5h:// отправляет прокси имя хоста, и резолвит уже он. Почти всегда нужен именно этот вариант

curl следует тому же правилу и пишет это так же. Флаг --socks5-hostname равен префиксу socks5h://.

# curl
curl -x socks5h://LOGIN:PASSWORD@IP:PORT https://ipinfo.io/json

# requests
PROXY = "socks5h://LOGIN:PASSWORD@IP:PORT"
proxies = {"http": PROXY, "https": PROXY}

У HTTP-прокси такого разделения нет: запрос CONNECT всегда несёт имя хоста, и резолвит его прокси. Если SOCKS не нужен по конкретной причине, HTTP на одну возможную ошибку меньше.

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

Запросите https://ipinfo.io/json через прокси и ещё раз без него. Поле ip должно отличаться, а с прокси поля country, region и org описывают сеть прокси, а не вашу. IP другой, значит вы прошли.

Вторая проверка, которая экономит отладку потом: запустите curl с -v. В логе должны быть CONNECT geekproxy.io:443 HTTP/1.1, строка Proxy-Authorization: Basic и ответ прокси 200 Connection established. Нет двухсотки, значит проблема между вами и прокси, а не с целевым сайтом.

Терминал, curl -v показывает CONNECT-туннель
Терминал: подробный вывод curl с запросом CONNECT, заголовком Proxy-Authorization и ответом 200 Connection established

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

Парсингу в объёме нужно много разных выходов, поэтому Residential Turbo или Residential Flex в режиме ротации: каждое новое соединение может выйти с другого домашнего IP, а sticky-сессия в логине держит один адрес столько, сколько нужно сценарию входа. Опрос API, который держит ваш адрес в белом списке, или любая задача, где неделями нужен один и тот же IP, это работа для статического ISP или датацентра IPv4, где у плана с оплатой за IP вообще нет счётчика трафика. Flex работает только по TCP. Здесь это не мешает: requests и curl UDP не используют.

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

curl: (7) Failed to connect или (28) Timeout was reached

Неверный хост или порт прокси, план истёк, или порт режет файрвол. Сначала проверьте кабинет, потом тот же host:port через nc -vz host port.

407 Proxy Authentication Required

Не сходятся логин или пароль, либо план в режиме белого списка, а вашего текущего IP в нём нет. Пароли с @, : или # внутри URL нужно кодировать процентами или передавать через -U в curl.

requests игнорирует прокси сессии

Задан прокси в окружении, и он важнее session.proxies. Снимите переменную, поставьте trust_env = False у сессии или передавайте proxies= в каждый вызов.

Missing dependencies for SOCKS support

Так requests сообщает, что PySocks не установлен. Выполните pip install "requests[socks]" в том же интерпретаторе, который запускает скрипт.

На ротируемом плане каждый запрос показывает один IP

Для Session это нормально: keep-alive переиспользует соединение, а выход привязан к соединению. Закройте сессию или делайте вызовы без неё, и следующее соединение сменит адрес.

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

Прокси для ваших скриптов

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

Заказать

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

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