Настройка прокси в aiohttp

Прокси в aiohttp для Python: параметр proxy в запросе, логин и пароль в адресе, SOCKS5 через aiohttp-socks и выбор порта для параллельных запросов.

Обновлено · Редакция Prokso

Данные для подключения
Хост
gw.prokso.com
Порт
823 HTTP · 824 SOCKS5 — новый IP на каждый запрос · 10000–20000 фиксированный IP (sticky-сессия), HTTP(S) и SOCKS5
Логин и пароль
в кабинете, на странице плана

Готовые строки в нужном формате генерирует кабинет: выберите страну, тип IP и протокол.

Коротко
  • Хост — gw.prokso.com, порты 823 (HTTP), 824 (SOCKS5), 10000–20000 (фиксированный IP, HTTP или SOCKS5)
  • Логин и пароль — в кабинете на странице плана
  • Проверяйте IP в ответе самого запроса через прокси: страница «Мой IP» в браузере ваш скрипт не проверяет
Прокси в aiohttp: короткая видеоинструкция · 0:34

Пошаговая инструкция, как подключить прокси Prokso в aiohttp. Займёт несколько минут.

Шаг 1. Возьмите данные прокси в кабинете

Откройте план и скопируйте хост gw.prokso.com, порт, логин и пароль. Порт 823 — HTTP, 824 — SOCKS5 (оба дают новый IP на каждый запрос); порты 10000–20000 — фиксированный IP до 120 минут, работают и как HTTP, и как SOCKS5 (каждый порт — отдельный адрес). Страну задают в логине: логин__cr.ua.

Блок «Доступ» на странице плана: хост, порты, логин и пароль для строки прокси
Блок «Доступ» на странице плана: хост, порты, логин и пароль для строки прокси

Шаг 2. Установите библиотеку

pip install aiohttp. Для SOCKS5 дополнительно понадобится pip install aiohttp-socks.

Шаг 3. Передайте прокси в запрос

aiohttp принимает HTTP-прокси в параметре proxy каждого запроса. Логин и пароль впишите прямо в адрес.

import asyncio
import aiohttp

PROXY = "http://ЛОГИН:ПАРОЛЬ@gw.prokso.com:823"


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


asyncio.run(main())
Пример запуска: в выводе — IP прокси, а не ваш. На порту 823 каждый запуск даёт новый адрес
Пример запуска: в выводе — IP прокси, а не ваш. На порту 823 каждый запуск даёт новый адрес

Шаг 4. SOCKS5 через aiohttp-socks

Сам aiohttp SOCKS не поддерживает. Создайте ProxyConnector из пакета aiohttp-socks и передайте его сессии — тогда все запросы сессии пойдут через SOCKS5.

import asyncio
import aiohttp
from aiohttp_socks import ProxyConnector


async def main():
    connector = ProxyConnector.from_url("socks5://ЛОГИН:ПАРОЛЬ@gw.prokso.com:824")
    async with aiohttp.ClientSession(connector=connector) as session:
        async with session.get("https://api.ipify.org?format=json") as r:
            print(await r.json())


asyncio.run(main())

Шаг 5. Много запросов одновременно

Для параллельного сбора данных берите порт 823 (или 824 для SOCKS5): каждый запрос получит новый адрес. Чтобы держать один IP для серии запросов, используйте фиксированный порт 10000–20000.

Шаг 6. Проверьте вывод

Запустите пример: скрипт обращается к https://api.ipify.org и печатает IP, который видит сайт. Это должен быть адрес прокси, а не ваш. Ошибка 407 означает неверный логин или пароль. Страница «Мой IP» в браузере здесь не поможет: браузер идёт напрямую.

Ограничение параллельности и тайм-ауты

aiohttp легко запускает тысячи запросов одновременно, и именно это чаще всего приводит к ошибкам 429 и тайм-аутам. Ограничьте число одновременных запросов семафором и задайте общий тайм-аут сессии:

import asyncio
import aiohttp

PROXY = "http://USERNAME:PASSWORD@gw.prokso.com:823"
URLS = ["https://prokso.com/ip"] * 20


async def fetch(session, sem, url):
    async with sem:                                   # no more than 10 requests at once
        async with session.get(url, proxy=PROXY) as r:
            return r.status, await r.text()


async def main():
    sem = asyncio.Semaphore(10)
    timeout = aiohttp.ClientTimeout(total=30)
    async with aiohttp.ClientSession(timeout=timeout) as session:
        results = await asyncio.gather(*(fetch(session, sem, u) for u in URLS), return_exceptions=True)
    print(results)


asyncio.run(main())

return_exceptions=True не даёт одному сбойному запросу отменить остальные: ошибки вернутся в списке результатов, и их можно повторить отдельно.

Что означают ошибки

  • ClientHttpProxyError, статус 407. Прокси не принял логин или пароль либо закончился трафик.
  • ClientProxyConnectionError. Не удалось соединиться с прокси: проверьте хост и порт.
  • asyncio.TimeoutError. Запрос не уложился в тайм-аут. Повторите его или увеличьте предел.
  • ServerDisconnectedError. Соединение оборвалось. Обычно помогает повтор и меньшая параллельность.

Коды 403 и 429 приходят от сайта — что с ними делать, описано на странице ошибки 429.

Один IP для группы запросов

Каждый запрос на порту 823 уходит с нового IP. Если несколько запросов должны идти с одного адреса — вход, затем страницы аккаунта — используйте для них фиксированный порт и отдельную сессию: так cookie и IP останутся согласованными.

Вопросы и ответы

Берёт ли aiohttp прокси из переменных окружения?

Только если создать сессию с параметром <code>trust_env=True</code> — тогда он прочитает HTTP_PROXY и HTTPS_PROXY. Надёжнее передавать прокси явно, как в примере.

Сколько одновременных запросов можно запускать?

План допускает до 1000 одновременных соединений. Ограничивайте параллельность в коде (например, семафором), чтобы не превысить лимит и не перегрузить целевой сайт.

Можно ли задать прокси один раз для всей сессии?

В актуальных версиях aiohttp параметр <code>proxy</code> принимает и сама сессия. В старых версиях его нужно передавать в каждый запрос.

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

Пропустите логин и пароль через <code>urllib.parse.quote(..., safe="")</code> или передайте их отдельно через <code>proxy_auth=aiohttp.BasicAuth(...)</code>.