Как подключить прокси в Python: requests, httpx, aiohttp и Playwright

Как подключить прокси в Python: requests, httpx, aiohttp и Playwright

Прокси в Python подключается одной строкой адреса вида http://логин:пароль@хост:порт, но у каждой библиотеки свой параметр: proxies в requests, proxy в httpx и aiohttp, словарь proxy в Playwright. Ниже — рабочие примеры для всех четырёх и разбор ошибок, на которых спотыкаются чаще всего.

Коротко

  • Адрес прокси для Python собирается в формате схема://логин:пароль@хост:порт; спецсимволы в пароле нужно закодировать.
  • requests и httpx умеют SOCKS5 только с дополнительным пакетом, aiohttp — через отдельную библиотеку aiohttp-socks.
  • Chromium в Playwright не поддерживает SOCKS5 с логином и паролем — используйте HTTP-прокси или авторизацию по IP.
  • Прежде чем запускать сбор, проверьте внешний IP одним запросом: так сразу видно, идёт ли трафик через прокси.

Как выглядит адрес прокси для Python

Все библиотеки ниже принимают адрес прокси в виде строки адреса (URL). Она состоит из схемы, данных для входа, хоста и порта:

Формат адреса

http://login:password@host:port
socks5://login:password@host:port
socks5h://login:password@host:port

Схема говорит библиотеке, каким протоколом общаться с прокси, а не с целевым сайтом. Через HTTP-прокси спокойно открываются и HTTPS-страницы: клиент просит прокси открыть туннель (метод CONNECT), и шифрование идёт напрямую между вами и сайтом. Подробнее о разнице протоколов — в статье «HTTP, HTTPS и SOCKS5: сравнение прокси-протоколов».

Термины статьи

http:// — клиент общается с прокси по HTTP; подходит и для HTTP-, и для HTTPS-сайтов.

socks5:// — протокол SOCKS5, имя сайта превращается в IP-адрес на вашей стороне.

socks5h:// — тот же SOCKS5, но имя сайта отправляется прокси и разрешается уже там; DNS-запросы не уходят с вашей машины напрямую.

Важно. Если в логине или пароле есть символы @, :, /, # или %, библиотека неправильно разберёт адрес. Закодируйте их через urllib.parse.quote(password, safe="") — пример есть в разделе об ошибках.

Прокси в requests

В requests прокси передаётся словарём: ключ — схема целевого сайта, значение — адрес прокси. Чтобы трафик шёл через прокси и для HTTP-, и для HTTPS-сайтов, нужны оба ключа.

Python

import requests

proxy = "http://login:password@host:port"
proxies = {"http": proxy, "https": proxy}

response = requests.get(
    "https://api.ipify.org?format=json",
    proxies=proxies,
    timeout=(10, 30),
)
print(response.json())

Если запросов много, удобнее один раз настроить сессию (requests.Session): она переиспользует соединения и держит прокси для всех запросов.

Python

session = requests.Session()
session.proxies.update(proxies)

for url in urls:
    r = session.get(url, timeout=(10, 30))

Для SOCKS5 поставьте дополнительный пакет и замените схему в адресе на socks5h://:

Терминал

pip install "requests[socks]"

Прокси в httpx

В httpx начиная с версии 0.26 прокси задаётся параметром proxy. Старый параметр proxies в версии 0.28 убрали, поэтому примеры из старых статей могут падать с ошибкой.

Python

import httpx

proxy = "http://login:password@host:port"

with httpx.Client(proxy=proxy, timeout=30) as client:
    r = client.get("https://api.ipify.org?format=json")
    print(r.json())

Асинхронный клиент настраивается так же: httpx.AsyncClient(proxy=proxy). Для SOCKS5 нужен пакет httpx[socks].

Прокси в aiohttp

В aiohttp прокси передаётся в каждый запрос параметром proxy. Встроенно поддерживаются только HTTP-прокси — HTTPS-сайты через них тоже открываются.

Python

import asyncio
import aiohttp

PROXY = "http://login:password@host:port"

async def main():
    timeout = aiohttp.ClientTimeout(total=30)
    async with aiohttp.ClientSession(timeout=timeout) as session:
        async with session.get("https://api.ipify.org?format=json", proxy=PROXY) as r:
            print(await r.json())

asyncio.run(main())

Для SOCKS5 используется библиотека aiohttp-socks: прокси задаётся не в запросе, а в соединителе (connector) сессии.

Python

from aiohttp_socks import ProxyConnector

connector = ProxyConnector.from_url("socks5://login:password@host:port")
async with aiohttp.ClientSession(connector=connector) as session:
    ...

Прокси в Playwright

Playwright управляет настоящим браузером, поэтому прокси задаётся при его запуске словарём с отдельными полями для сервера, логина и пароля.

Python

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(proxy={
        "server": "http://host:port",
        "username": "login",
        "password": "password",
    })
    page = browser.new_page()
    page.goto("https://api.ipify.org?format=json")
    print(page.inner_text("body"))
    browser.close()

Если нужно несколько прокси в одном браузере, передайте такой же словарь в browser.new_context(proxy=...): у каждого контекста будет свой выход в сеть.

Важно. Chromium не поддерживает SOCKS5-прокси с логином и паролем. Для Playwright берите HTTP-прокси или включите авторизацию по IP-адресу — тогда логин и пароль не нужны.

Как проверить, что запросы идут через прокси

Самый быстрый способ — запросить сервис, который возвращает ваш внешний IP, сначала без прокси, потом с ним. Адреса должны отличаться. Удобно сделать это первым шагом скрипта, до основного сбора.

  1. Запросите IP без прокси.
    Это ваш адрес провайдера или сервера.
  2. Повторите запрос через прокси.
    Должен вернуться другой адрес.
  3. Сделайте несколько запросов подряд.
    Если прокси с ротацией, адрес будет меняться по выбранному правилу; статичный прокси вернёт один и тот же IP.

Как оценить качество прокси глубже — скорость, долю успешных ответов, геолокацию, — разобрали в статье «Как проверить качество прокси перед покупкой».

Частые ошибки при подключении

  • Ошибка 407 Proxy Authentication Required
    Прокси не принял логин или пароль. Проверьте данные в личном кабинете и закодируйте спецсимволы в пароле.
  • Трафик идёт мимо прокси
    В requests указан только ключ http, а сайт открывается по HTTPS. Добавьте ключ https с тем же адресом.
  • Прокси подхватился из окружения
    requests и httpx по умолчанию читают переменные HTTP_PROXY, HTTPS_PROXY и NO_PROXY. Если результат неожиданный, проверьте их или отключите параметром trust_env=False.
  • Ошибка о неизвестной схеме SOCKS
    Не установлен пакет для SOCKS: requests[socks], httpx[socks] или aiohttp-socks.
  • Скрипт зависает без ошибки
    Не задан таймаут. В requests по умолчанию его нет, и запрос может ждать ответа бесконечно.

Как закодировать пароль со спецсимволами:

Python

from urllib.parse import quote

login = "user"
password = quote("p@ss:w0rd#", safe="")
proxy = f"http://{login}:{password}@host:port"

Если прокси не подключается вовсе, пройдитесь по чек-листу из статьи «Почему прокси не подключается».

Как это устроено у нас

В личном кабинете Proxy.Market данные для подключения показаны в формате IP:PORT@LOGIN:PASSWORD. Для Python порядок нужно поменять: сначала логин и пароль, потом хост и порт — http://LOGIN:PASSWORD@IP:PORT.

Авторизоваться можно двумя способами: логином и паролем или по белому списку IP-адресов. Второй вариант удобен для Playwright и серверов с постоянным адресом — в строке прокси остаются только хост и порт.


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

Нужно ли указывать https:// в адресе прокси для HTTPS-сайтов?
Нет. Схема в адресе описывает протокол связи с прокси, а не с сайтом. HTTP-прокси открывает HTTPS-сайты через туннель, поэтому обычно достаточно http://.

Чем socks5 отличается от socks5h?
При socks5 имя сайта превращается в IP на вашей машине, при socks5h — на стороне прокси. Второй вариант не отправляет DNS-запросы мимо прокси.

Почему httpx ругается на параметр proxies?
В версии 0.28 параметр proxies удалили. Используйте proxy с одним адресом или параметр mounts, если нужны разные прокси для разных адресов.

Можно ли использовать SOCKS5 с паролем в Playwright?
В Chromium — нет, браузер не поддерживает авторизацию для SOCKS5. Используйте HTTP-прокси или авторизацию по IP-адресу.

Не получается подключить прокси?

Пришлите в поддержку библиотеку, фрагмент кода без пароля и текст ошибки — поможем разобраться.

Написать в поддержку