Прокси в Python: requests, httpx и Playwright

Опубликовано 6 минут чтения

Коротко

В requests прокси передают словарём proxies с ключами http и https, в httpx — аргументом proxy, в Playwright — параметром proxy с полями server, username и password. Для SOCKS5 в requests нужен пакет PySocks и схема socks5h. Chromium через Playwright не принимает SOCKS5 с логином и паролем, поэтому в браузере используйте HTTP: у Proxeta это порт 8080.

Ниже — как подключить прокси с логином и паролем в requests, httpx и Playwright для Python, как управлять сменой IP и как читать ошибки. Данные в примерах условные: подставьте свои из личного кабинета. Выходной IP примеры узнают у сервиса api64.ipify.org, который возвращает адрес, с которого к нему пришёл запрос.

Строка прокси в формате URL

Личный кабинет выдаёт строку host:port:login:password, а Python-библиотеки ждут URL: http://login:password@host:8080 для HTTP или socks5h://login:password@host:1080 для SOCKS5. Функция ниже переводит одно в другое и кодирует логин и пароль, если в них есть @, : или /:

from urllib.parse import quote

def proxy_url(line, scheme="http"):
    host, port, login, password = line.strip().split(":", 3)
    return f"{scheme}://{quote(login, safe='')}:{quote(password, safe='')}@{host}:{port}"

print(proxy_url("proxy.example.invalid:8080:login-country-us:password"))
print(proxy_url("proxy.example.invalid:1080:login-country-us:password", "socks5h"))

split(":", 3) делит строку не больше чем на четыре части, поэтому двоеточие в пароле не мешает. Логины в примерах сокращены: в строке из личного кабинета есть ещё параметр фильтра, например -filter-medium, поэтому копируйте её целиком. Из чего состоит логин, разобрано в статье формат строки прокси.

requests: HTTP и SOCKS5

Нужен пакет: pip install requests.

import requests

PROXY = "http://login-country-us:password@proxy.example.invalid:8080"
PROXIES = {"http": PROXY, "https": PROXY}

r = requests.get("https://api64.ipify.org?format=json", proxies=PROXIES, timeout=(10, 30))
r.raise_for_status()
print(r.json()["ip"])

Что важно в этом коде:

  • Оба ключа. Ключ словаря — схема сайта, значение — адрес прокси. Если указать только "http", запросы к https://-сайтам пойдут напрямую, мимо прокси.
  • Схема значения — http:// и для ключа "https": requests открывает к прокси обычное соединение и туннель CONNECT. https:// в адресе прокси означало бы TLS-соединение до самого прокси, а это другой тип прокси.
  • Таймаут. timeout=(10, 30) — 10 секунд на подключение и 30 на ожидание ответа. Без таймаута requests может ждать ответа бесконечно.

Для SOCKS5 поставьте пакет PySocks командой pip install "requests[socks]" и замените адрес:

PROXY = "socks5h://login-country-us:password@proxy.example.invalid:1080"

С socks5h:// имя сайта разрешает прокси, с socks5:// — ваше устройство, и адрес сайта может подбираться для вашей локации, а не для локации выхода; подробнее — в статье HTTP или SOCKS5. Без PySocks requests остановится с ошибкой Missing dependencies for SOCKS support.

Сессии и смена IP

При ротации (логин без -sid-) новый IP получает каждое новое соединение. requests.Session держит соединение открытым и отправляет через него следующие запросы, а requests.get без сессии каждый раз открывает новое. Сравните:

import requests

PROXY = "http://login-country-us:password@proxy.example.invalid:8080"
PROXIES = {"http": PROXY, "https": PROXY}
URL = "https://api64.ipify.org?format=json"

with requests.Session() as session:
    print([session.get(URL, proxies=PROXIES, timeout=(10, 30)).json()["ip"] for _ in range(3)])

print([requests.get(URL, proxies=PROXIES, timeout=(10, 30)).json()["ip"] for _ in range(3)])

Первая строка вывода — три одинаковых адреса: все запросы прошли через одно соединение. Во второй адреса меняются: у каждого запроса своё соединение. Если сервер закроет соединение сессии, она откроет новое, и при ротации адрес тоже сменится.

Если адрес должен сохраняться между запросами — например, после входа в аккаунт или на шагах формы, — возьмите строку липкой сессии с -sid-: с ней все шесть запросов из примера выходят с одного адреса, пока жива сессия. Когда какой режим выбирать, разобрано в статье sticky-сессия или ротация.

httpx

Нужен пакет: pip install httpx. httpx принимает прокси аргументом proxy; старый аргумент proxies в версии 0.28 удалён, и с ним клиент не создаётся.

import httpx

PROXY = "http://login-country-us:password@proxy.example.invalid:8080"

with httpx.Client(proxy=PROXY, timeout=30) as client:
    r = client.get("https://api64.ipify.org?format=json")
    r.raise_for_status()
    print(r.json()["ip"])

Тот же аргумент принимает асинхронный клиент:

import asyncio
import httpx

PROXY = "http://login-country-us:password@proxy.example.invalid:8080"

async def main():
    async with httpx.AsyncClient(proxy=PROXY, timeout=30) as client:
        r = await client.get("https://api64.ipify.org?format=json")
        r.raise_for_status()
        print(r.json()["ip"])

asyncio.run(main())

Клиент httpx тоже держит соединения открытыми, поэтому при ротации запросы одного клиента могут выходить с одного адреса. Для SOCKS5 httpx нужен дополнительный пакет httpx[socks], а без него клиент остановится с ошибкой ImportError; в этой статье SOCKS5 показан на requests.

Playwright: прокси с логином и паролем

Нужны пакет и браузер: pip install playwright и playwright install chromium.

from playwright.sync_api import sync_playwright

PROXY = {
    "server": "http://proxy.example.invalid:8080",
    "username": "login-country-us-sid-k7m2q9x4ab",
    "password": "password",
}

with sync_playwright() as p:
    browser = p.chromium.launch(proxy=PROXY)
    try:
        page = browser.new_page()
        page.goto("https://api64.ipify.org?format=json", timeout=60000)
        print(page.inner_text("body"))
    finally:
        browser.close()
  • Поля. Логин и пароль передаются отдельными полями username и password, а в server — только схема, хост и порт.
  • Липкая сессия. Браузер открывает несколько соединений даже на одну страницу, и при ротации они могли бы выйти с разных адресов. Поэтому в примере строка с -sid-.

Если разным задачам нужны разные адреса, задайте прокси на уровне контекста: у каждого контекста свои cookies и свой прокси. В примере ниже один контекст выходит из США, другой — из Германии:

from playwright.sync_api import sync_playwright

LOGINS = ["login-country-us-sid-k7m2q9x4ab", "login-country-de-sid-p3w8n1c5zd"]

with sync_playwright() as p:
    browser = p.chromium.launch()
    try:
        for login in LOGINS:
            context = browser.new_context(proxy={
                "server": "http://proxy.example.invalid:8080",
                "username": login,
                "password": "password",
            })
            page = context.new_page()
            page.goto("https://api64.ipify.org?format=json", timeout=60000)
            print(login, page.inner_text("body"))
            context.close()
    finally:
        browser.close()

Почему не SOCKS5

Chromium через Playwright не работает с SOCKS5 по логину и паролю. Запуск с "server": "socks5://proxy.example.invalid:1080" и полями username и password останавливается ошибкой Browser does not support socks5 proxy authentication. Если вместо этого записать логин и пароль в сам адрес socks5://, запуск проходит, но браузер их не передаёт: он предлагает прокси только подключение без входа, прокси с обязательным логином отказывает, и page.goto завершается ошибкой net::ERR_SOCKS_CONNECTION_FAILED. Поэтому в Playwright используйте HTTP — порт 8080. Firefox и WebKit мы не проверяли.

Ошибки и что они значат

Номер ошибки в Connection refused зависит от системы: на macOS это [Errno 61], на Linux — [Errno 111].

БиблиотекаСообщениеЧто это значит
requestsProxyError: ... Tunnel connection failed: 407 Proxy Authentication RequiredHTTP-прокси не принял логин или пароль
requestsConnectionError: ... SOCKS5 authentication failedSOCKS5-прокси не принял логин или пароль
requestsProxyError: ... Failed to establish a new connection: [Errno 61] Connection refusedСоединение с прокси не установилось: неверный порт или исходящие соединения закрыты в вашей сети
requestsProxyError: ... Failed to resolve 'proxy.example.invalid'Адрес прокси не найден. Так завершается и пример без замены условного хоста
requestsInvalidSchema: Missing dependencies for SOCKS support.Не установлен PySocks: pip install "requests[socks]"
httpxProxyError: 407 Proxy Authentication RequiredПрокси не принял логин или пароль
httpxConnectError: [Errno 61] Connection refusedСоединение с прокси не установилось
Playwrightnet::ERR_PROXY_CONNECTION_FAILEDСоединение с прокси не установилось
Playwrightnet::ERR_SOCKS_CONNECTION_FAILEDСоединение через SOCKS5-прокси не установилось. Так заканчивается и попытка записать логин и пароль в адрес socks5://: Chromium их не передаёт
PlaywrightTimeout 60000ms exceededСтраница не загрузилась за отведённое время. В нашей проверке так выглядел и неверный пароль: Chromium не показал код 407

Если Playwright упирается в таймаут, проверьте ту же строку в requests или curl: там неверный логин или пароль видны по коду 407. Разбор ошибок curl — в статье curl через прокси.

Прокси не меняет правил сайта. Соблюдайте его условия и robots.txt, ограничивайте частоту запросов и не отвечайте на отказ сменой IP: подробнее — в руководстве по прокси для парсинга.

Как запускались примеры

Примеры запускались 5 ноября 2026 года на macOS в Python 3.11 с requests 2.33.1, PySocks 1.7.1, httpx 0.28.1 и Playwright 1.58.0 для Python — через локальные тестовые HTTP- и SOCKS5-прокси с логином и паролем и локальный сайт, а не через шлюз Proxeta. Обе проверки SOCKS5 в Playwright мы повторили в Playwright 1.62.1 для Node.js с Chromium 151. Для теста браузеру разрешили сертификат локального сайта. Так проверяются синтаксис и поведение библиотек, но не выходные IP и работа настоящей сети.

Частые вопросы

Как подключить прокси с логином и паролем в requests?

Передайте словарь proxies, где оба ключа, http и https, указывают на адрес вида http://логин:пароль@хост:8080. Если указать только http, запросы к https://-сайтам пойдут мимо прокси. Для SOCKS5 установите requests[socks] и используйте адрес socks5h://логин:пароль@хост:1080.

Почему Playwright не принимает SOCKS5 с паролем?

Chromium через Playwright не поддерживает вход в SOCKS5-прокси по логину и паролю: запуск останавливается ошибкой «Browser does not support socks5 proxy authentication». Мы проверили это 5 ноября 2026 года в Playwright 1.62.1 для Node.js с Chromium 151 и в Playwright 1.58.0 для Python. Используйте HTTP-прокси, у Proxeta это порт 8080.

Как получать новый IP на каждый запрос в Python?

Возьмите строку с ротацией, без параметра -sid- в логине, и открывайте новое соединение на каждый запрос: например, вызывайте requests.get без общей сессии. requests.Session держит соединение открытым, и через одно соединение запросы выходят с одного адреса.

Как задать разные прокси для разных контекстов Playwright?

Передайте параметр proxy в browser.new_context, а не в chromium.launch: у каждого контекста будут свои cookies и свой прокси. Для каждого контекста берите отдельную строку липкой сессии, чтобы все его соединения выходили с одного адреса.

Читайте также

Все статьи

Опубликовано 6 минут чтения

curl через прокси: HTTP, SOCKS5 и частые ошибки

Как работать с curl через прокси: HTTP и SOCKS5 с логином и паролем, socks5h или socks5, проверка выходного IP и что значат ошибки 407 и Connection refused.

Читать статью

Опубликовано 5 минут чтения

HTTP или SOCKS5: какой протокол прокси выбрать

Чем HTTP-прокси отличается от SOCKS5: как они передают запросы, кто разрешает DNS, почему через шлюз не проходят UDP и QUIC и какой порт выбрать в Proxeta.

Читать статью