Проксі в 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].
| Бібліотека | Повідомлення | Що це означає |
|---|---|---|
| requests | ProxyError: ... Tunnel connection failed: 407 Proxy Authentication Required | HTTP-проксі не прийняв логін або пароль |
| requests | ConnectionError: ... SOCKS5 authentication failed | SOCKS5-проксі не прийняв логін або пароль |
| requests | ProxyError: ... Failed to establish a new connection: [Errno 61] Connection refused | З’єднання з проксі не встановилося: неправильний порт або вихідні з’єднання закрито у вашій мережі |
| requests | ProxyError: ... Failed to resolve 'proxy.example.invalid' | Адресу проксі не знайдено. Так завершується й приклад без заміни умовного хоста |
| requests | InvalidSchema: Missing dependencies for SOCKS support. | Не встановлено PySocks: pip install "requests[socks]" |
| httpx | ProxyError: 407 Proxy Authentication Required | Проксі не прийняв логін або пароль |
| httpx | ConnectError: [Errno 61] Connection refused | З’єднання з проксі не встановилося |
| Playwright | net::ERR_PROXY_CONNECTION_FAILED | З’єднання з проксі не встановилося |
| Playwright | net::ERR_SOCKS_CONNECTION_FAILED | З’єднання через SOCKS5-проксі не встановилося. Так закінчується й спроба записати логін і пароль в адресу socks5://: Chromium їх не передає |
| Playwright | Timeout 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 і свій проксі. Для кожного контексту беріть окремий рядок липкої сесії, щоб усі його з’єднання виходили з однієї адреси.