Перейти к содержанию

Руководство · На русском

Прокси в Python urllib: настройка и проверка

Стандартная библиотека Python умеет отправлять HTTPS-запрос через HTTP-прокси. Создайте отдельный opener, передайте ему явную конфигурацию и проверьте один небольшой ответ. Настройка urllib не меняет Requests, HTTPX или сетевой маршрут других программ.

Каталог и инструкции — на русском. Страница отдельного товара, аккаунт, корзина, оплата и полные условия обслуживания пока доступны на английском.

Опубликовано:

Короткие ответы

Как задать прокси для urllib.request?

Передайте словарь в ProxyHandler, создайте build_opener и используйте open именно этого объекта. Ключ https выбирает назначения HTTPS; URL в значении описывает шлюз. Здесь не устанавливается глобальный opener.

Куда передавать логин и пароль?

Этот пример отдельно кодирует исходный логин и пароль как компоненты URL прокси. Пароль читается через скрытый ввод. Не вставляйте его в исходник, аргументы оболочки или открытый отчёт.

407 всегда будет HTTPError?

Нет. Отклонённый CONNECT может привести к URLError до получения HTTP-ответа назначения. Общее сообщение ошибки не доказывает неверный пароль: отдельно проверяются адрес, TLS и содержимое ответа.

Таймаут десять секунд ограничивает весь скрипт?

Нет. Он относится к блокирующим операциям сокета. У задания дополнительно должны быть общий срок, ограничение работы и намеренная политика повторов. Ограничение прочитанного тела — ещё одна отдельная граница.

Проверьте, какой клиент использует приложение

urllib.request поставляется с Python и не требует установки стороннего HTTP-пакета. Если рабочий код использует Requests или HTTPX, настройте этот клиент по его правилам. Одинаковый язык Python не делает сетевую конфигурацию общей для библиотек.

Исходный пример проверялся на CPython 3.12.14 в локальных фикстурах HTTP CONNECT и HTTPS, без живого пула Portproof. Это граница сохранённого примера, а не заявление о проверке всех версий и операционных систем. Перед переносом проверьте свой интерпретатор и поддержку SSL.

Соберите параметры HTTP-подключения

  1. Откройте Connection builder · English, выберите HTTP, нужный пул, доступную страну и ротацию.
  2. Сохраните полное имя пользователя с параметрами подключения; одна основа аккаунта недостаточна.
  3. Подготовьте текущий пароль прокси. Не заменяйте его паролем Portproof или ключом API.
  4. Сохраните код ниже как proxy_check.py и запустите python3 proxy_check.py в интерактивном терминале.

Скрипт остановится, если терминал не умеет скрывать пароль. Не исправляйте это вставкой секрета в код. Скрытый ввод защищает отображение, но не заражённое устройство или память процесса. Не публикуйте полный URL прокси и необработанный объект исключения.

Один запрос через отдельный opener

proxy_check.py — стандартная библиотекаpython
import getpass
import http.client
import ipaddress
import json
import ssl
import warnings
from urllib.error import HTTPError, URLError
from urllib.parse import quote, urlsplit
from urllib.request import (
    HTTPRedirectHandler, HTTPSHandler, ProxyHandler,
    build_opener, proxy_bypass,
)

TARGET = "https://api.portproof.org/v1/echo-ip"
GATEWAY = "gw.portproof.org:7000"

class NoRedirect(HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None

def main():
    try:
        # Stop if a terminal cannot hide the password.
        warnings.simplefilter("error", getpass.GetPassWarning)
        username = input("Full proxy username: ").strip()
        password = getpass.getpass("Proxy password: ")
        if not username or not password:
            raise ValueError("Empty credential")
        if proxy_bypass(urlsplit(TARGET).netloc):
            print("A direct-routing exception matches the target. Review NO_PROXY or system proxy exceptions.")
            return 1
        credential = quote(username, safe="") + ":" + quote(password, safe="")
        proxy = "http://" + credential + "@" + GATEWAY
        context = ssl.create_default_context()
        context.set_alpn_protocols(["http/1.1"])
        opener = build_opener(
            ProxyHandler({"https": proxy}),
            HTTPSHandler(context=context),
            NoRedirect(),
        )
        with opener.open(TARGET, timeout=10) as response:
            if response.status != 200:
                raise ValueError("Unexpected response")
            body = response.read(16_385)
        if len(body) > 16_384:
            raise ValueError("Response too large")
        payload = json.loads(body)
        if not isinstance(payload, dict) or not isinstance(payload.get("ip"), str):
            raise ValueError("Missing IP")
        print("HTTP 200; exit IP:", ipaddress.ip_address(payload["ip"]))
        return 0
    except HTTPError as error:
        print("HTTP status:", error.code)
        error.close()
    except getpass.GetPassWarning:
        print("Run from an interactive terminal that supports hidden password input.")
    except (URLError, OSError, ValueError, http.client.HTTPException):
        print("Check failed. Check proxy settings, credentials, TLS and the echo response.")
    except (EOFError, KeyboardInterrupt):
        print("Check cancelled.")
    return 1

if __name__ == "__main__":
    raise SystemExit(main())

Ожидается HTTP 200 и JSON с корректным IP. Вывод описывает то, что увидело назначение для этого запроса. Он не подтверждает географию, будущий адрес или разрешение другого сайта. При проверке используется существующий трафик; новый заказ или финансовая операция не выполняются.

Разделите схему назначения и транспорт шлюза

В ProxyHandler ключ https указывает на HTTPS-назначение, а http:// в значении — на HTTP-шлюз. После CONNECT выполняется TLS с назначением. Не меняйте схему шлюза только из-за HTTPS в адресе страницы. Документация Python описывает обработчики, openers и исключения окружения.

quote(value, safe="") применяется отдельно к исходным значениям. Символы @, двоеточие, косая черта и процент не должны превратить пароль в другую часть URL. Не кодируйте целый URL и не повторяйте кодирование уже преобразованного пароля. Для полного логина используйте результат конструктора, не собирайте его вручную.

Прокси-авторизация и вход на сайт назначения раздельны. Исходник не задаёт логин сайта. TLS-проверка назначения остаётся включённой, но начальная передача Basic-данных HTTP-шлюзу не зашифрована этим TLS. Используйте доверенный путь к шлюзу; принимайте только допустимую цепочку сертификата.

Учтите исключения и границы чтения

Явный словарь не выбирает адрес шлюза из переменных среды, однако исключения прямого маршрута всё ещё имеют значение. Пример проверяет proxy_bypass и останавливается при совпадении. Просмотрите NO_PROXY, no_proxy и системные исключения локально. Не удаляйте политику рабочей сети ради успешного результата.

Opener принадлежит проверке: install_opener не вызывается, чужие запросы не получают новую глобальную конфигурацию. Перенаправления остановлены. Ответ 301 или 302 здесь означает необходимость проверить назначение, а не включить неограниченный переход на другие узлы.

Читается максимум 16 КиБ плюс байт для обнаружения превышения. Это не предел всего сетевого расхода и не общий таймер. Длительный поток, очередь заданий и повторные попытки требуют дополнительных ограничений в приложении. Не расширяйте одноразовую проверку до рабочего сборщика без такого решения.

Определите, получен ли ответ назначения

Следующий шаг по результату
НаблюдениеЧто проверить
HTTP 401 или 403Назначение ответило внутри туннеля: проверить его правила, не подставлять пароль шлюза.
Ошибка до HTTP-статусаСверить CONNECT, адрес, TLS и формат ответа через проверку curl.
301, 302, 307 или 308Пример не следует перенаправлению; проверить ожидаемый URL.
Сообщение о прямом исключенииПроверить источник окружения и политику маршрута.
Нельзя скрыть парольИспользовать подходящий терминал, не оставлять пароль в исходнике.

Для авторизации есть инструкция 407, а при разных результатах клиентов — сравнение среды приложения. Меняйте один фактор и сохраняйте короткий результат без секретов.

Сохраните область действия примера

Использованный стандартный обработчик — HTTP-клиент прокси; SOCKS5 он не добавляет. Opener Python также не равен sticky-сессии шлюза. Выберите сессию в полном имени пользователя и сохраняйте одну конфигурацию для связанных шагов. Общие мобильный и резидентский пулы не гарантируют постоянный IP.

Перед большим заданием измерьте собственный разрешённый сценарий и ознакомьтесь с тарифами. Кабинет и покупка остаются на английском. Официальные справки проверены 31 октября 2026 года; тело сохранённого примера не изменено. Новая проверка живого шлюза, скорости или страны не проводилась.

Допустимое использование

Используйте прокси для разрешённых задач и соблюдайте правила принимающего сервиса. Настройка соединения не даёт права на доступ. Применяются правила допустимого использования · English.

Следующий шаг