Формат прокси листа: IP:PORT и IP:PORT:LOGIN:PASS, как загрузить список в программу
- Как читается строка и что означает каждое поле
- Два формата выдачи и когда берут каждый из них
- Привязка адреса в кабинете и доступ по логину
- Схема в начале строки: http, socks5 и socks5h
- Ссылка на список и файл: как забирать выдачу
- Форматы под разные программы: расширение и антидетект-браузер
- Парсер со своим менеджером списка и подстановка из кода
- Пять причин сорванной загрузки списка
- Как проверить строку до загрузки в софт
- Как обновлять список без остановки работы
Прокси-лист это текстовый файл, где одна строка описывает один узел пула. Разметки внутри нет, поля разделяются двоеточием, строки отделяются переводом строки. Такой файл читает и человек, и программа, никакой подготовки перед загрузкой он не требует. В пуле iprazon список отдаётся в двух видах, IP:PORT и IP:PORT:LOGIN:PASS, забрать его можно ссылкой или файлом, обновляется выдача в режиме реального времени.
Я загружаю списки в четыре разных типа программ и делаю это по несколько раз в неделю. Ошибки у людей повторяются одни и те же, и почти все они относятся к тексту строки, пока сам пул отвечает нормально. Дальше я разбираю строку по полям, показываю оба формата выдачи, оба режима допуска и порядок загрузки в конкретный софт.
Как читается строка и что означает каждое поле
Короткая строка выглядит так: 203.0.113.24:8080. Слева адрес узла, справа номер порта, между ними двоеточие. Полная строка добавляет ещё два поля: 203.0.113.24:8080:u84512:k39dhzp. Третьим идёт имя доступа, четвёртым пароль. Порядок полей закреплён и никогда не меняется. Программа режет строку по двоеточию и раскладывает куски по позициям, поэтому смысл каждого куска задаётся его номером, никаких подписей внутри строки нет.
Первое поле почти всегда содержит четыре октета IPv4. Иногда в первом поле стоит доменное имя вида gate.example.net, и тогда программа сама превращает его в адрес перед подключением. Второе поле важнее, чем кажется на первый взгляд: у одного и того же узла порт под HTTP и порт под SOCKS5 разные. Взять адрес из HTTP-выдачи и вписать его в поле SOCKS5-клиента получится, работать это не будет: клиент отправит на порт приветствие своего протокола, сервер его не поймёт, соединение оборвётся без внятного текста в логе.
Третье и четвёртое поля появляются только в расширенном формате. Имя доступа и пароль в выдаче одинаковы по всей длине списка, они относятся к пакету целиком. Единственное, за чем я слежу отдельно: двоеточие внутри пароля. Если оно там окажется, разбор строки по позициям поедет, четвёртое поле обрежется на середине, и софт получит неверный пароль при полностью верном адресе. Проверить это стоит один раз, сразу после первой выдачи.
| Поле | Что содержит | Пример | Что ломается при ошибке в нём |
|---|---|---|---|
| Адрес | Узел пула, четыре октета IPv4 | 203.0.113.24 | Соединение не устанавливается, тайм-аут |
| Порт | Номер порта нужного протокола | 8080 для HTTP, 1080 для SOCKS5 | Обрыв на приветствии, лог молчит |
| Логин | Имя доступа из кабинета | u84512 | Код 407 у HTTP, отказ на этапе метода у SOCKS5 |
| Пароль | Пароль доступа к пулу | k39dhzp | Тот же отказ по допуску, адрес при этом рабочий |
Порт стоит держать в конфиге отдельным полем. Склейка порта со строкой руками добавляет ровно один шанс промахнуться на каждую правку. Я храню два значения на пакет и подставляю нужное по схеме подключения, потому что перепутанное значение даёт самую скучную из возможных отладок. Когда нужен именно веб-трафик и разбор ответов по кодам, я беру список HTTP-прокси в двух форматах и раскладываю его по потокам заранее, до старта прогона.
Два формата выдачи и когда берут каждый из них
Разница между IP:PORT и IP:PORT:LOGIN:PASS сводится к тому, где хранится допуск. В коротком формате допуск живёт на стороне сервиса: пул уже знает адрес машины, с которой к нему придут, и пускает по этому признаку. В длинном формате допуск едет вместе с каждой строкой, и пулу неважно, откуда именно пришёл запрос.
Короткий формат приятнее в работе с софтом, у которого поля для имени и пароля вынесены отдельно от поля адреса. Таких программ много: старые чекеры, часть менеджеров закачек, самописные скрипты с двумя переменными в конфиге. Длинный формат приятнее там, где строка одна на всё и разбирается автоматически: массовые загрузчики списков, антидетект-браузеры с пакетным импортом, планировщики задач.
Есть третий сценарий, о котором обычно вспоминают поздно. Список из 12 000 строк удобно раздавать между машинами по частям, и короткий формат для этого не годится: каждая машина должна быть привязана отдельно. Длинный формат переносится куда угодно как обычный текст, и я держу его основным именно поэтому.
Полезная мелочь: оба формата разбираются одним и тем же кодом, если считать поля по количеству. Двоеточий в строке одно значит формат короткий, три значит полный. Никаких флагов в конфиге держать не нужно.
def parse(line):
p = line.strip().split(":")
if len(p) == 2:
return {"host": p[0], "port": int(p[1])}
if len(p) == 4:
return {"host": p[0], "port": int(p[1]), "user": p[2], "pwd": p[3]}
raise ValueError("строка с неверным числом полей: " + line)
Эта функция у меня стоит первой в любом скрипте, который читает список. Она же ловит мусор: строка с двумя двоеточиями означает, что где-то потерялось поле, и такую запись лучше отбросить сразу, до загрузки в пул потоков.
Привязка адреса в кабинете и доступ по логину
Оба режима допуска дают одинаковый результат на выходе, различаются они удобством и тем, что придётся хранить. Привязка адреса настраивается в кабинете: вы вписываете туда адрес своей машины, и пул начинает пускать запросы с него без пароля. В пакет входит две привязки одновременно, менять их можно свободно и сколько угодно раз, поэтому переезд на другой канал занимает минуту.
Я держу привязку на стационарном стенде, где канал не меняется неделями. Строки в конфиге короткие, паролей в файлах нет, при передаче конфига коллеге ничего лишнего не утекает. Одна деталь тут заметна не сразу: при двух привязанных адресах общий лимит потоков делится между ними пополам. Если обе машины работают одновременно и вы рассчитывали на полный лимит, поведение под нагрузкой окажется неожиданным. Я планирую нагрузку сразу от половины, когда привязок две.
Доступ по логину я использую на всём, что живёт в облаке и меняет адрес при перезапуске. Виртуалка получила новый адрес после переезда, конфиг остался прежним, прогон продолжился. Плата за это одна: пароль лежит в конфигурационном файле, значит файл нужно закрывать правами доступа и не таскать его в общий репозиторий. Я держу такие конфиги отдельной директорией и подкладываю их на машину при развёртывании.
Смешивать режимы в пределах одного прогона незачем. Выберите один и держите его по всему парку машин, иначе через месяц вы будете помнить только про половину настроек. Когда важно, чтобы целевой узел видел ровно один выходной адрес без служебных заголовков сверху, я собираю прогон на анонимные приватные адреса из пула и оставляю на них длинный формат строки.
| Признак | Привязка адреса | Логин с паролем |
|---|---|---|
| Формат строки | IP:PORT | IP:PORT:LOGIN:PASS |
| Что настраивается | Адрес машины в кабинете | Ничего, допуск в строке |
| Смена канала | Правка привязки в кабинете | Ничего править не нужно |
| Сколько машин | Две привязки в пакете | Любое число машин |
| Потоки | При двух привязках делятся пополам | Общий лимит пакета |
| Что хранить | Только адреса и порты | Ещё имя доступа и пароль |
Схема в начале строки: http, socks5 и socks5h
Список отдаётся без схемы, схему подставляет программа. В большинстве полей ввода она подставляется автоматически, в коде и в командной строке её пишут руками. Полная запись выглядит так: socks5://u84512:k39dhzp@203.0.113.24:1080. Здесь схема, дальше имя и пароль через двоеточие, дальше собака, дальше адрес с портом. Тот же узел по HTTP пишется как http://u84512:k39dhzp@203.0.113.24:8080.
Схема описывает канал до пула, целевой сайт тут ни при чём. Строка с http:// спокойно обслуживает обращение к адресу на https: клиент шлёт пулу метод CONNECT, тот поднимает канал, дальше шифрование идёт между вашей программой и сайтом. Писать https:// в поле только потому, что целевая ссылка начинается с https, смысла нет, и такая правка даёт ошибку рукопожатия.
Отдельная история с буквой h в схеме socks5h. Она говорит клиенту передать доменное имя на сторону пула строкой и дать серверу превратить имя в адрес самому. Без неё имя превращается в адрес на вашей машине, и запрос в DNS уходит мимо пула. Разница проявляется в том, какой резолвер отвечает на вопрос, скорость тут одинаковая. Я ставлю socks5h везде, где программа эту схему понимает.
curl -x socks5h://u84512:k39dhzp@203.0.113.24:1080 https://api.ipify.org
curl -x http://u84512:k39dhzp@203.0.113.24:8080 https://api.ipify.org
Два вызова подряд, две проверки. Оба должны вернуть адрес узла пула, и оба должны вернуть разные адреса при повторе: ротация внутри пула идёт автоматически. Пакет включает SOCKS4 и SOCKS5 на выбор, я останавливаюсь на пятой версии всегда, у неё есть допуск по логину и работа с доменными именами. Когда прогон идёт к сайтам по защищённой схеме через тот же туннель CONNECT, я подключаю точку входа для запросов по HTTPS и держу под неё отдельное поле порта в конфиге.
Ссылка на список и файл: как забирать выдачу
В кабинете доступны два способа получить список: ссылка и скачивание файлом. Отличие простое. Файл это снимок на момент нажатия кнопки. Ссылка отдаёт текущее содержимое пула каждый раз, когда по ней пришли.
Файл я беру, когда список нужно показать глазами, разложить по машинам вручную или отдать программе, которая умеет только импорт с диска. Ссылку беру во всём, что работает по расписанию. Список обновляется в реальном времени, значит скрипт может забрать свежий вариант перед каждым запуском и не думать о том, насколько устарел файл на диске.
curl -s "https://cabinet.example/list/u84512/full" -o /opt/pool/list.txt
wc -l /opt/pool/list.txt
Две строки в задании планировщика, и парк машин всегда работает от актуальной выдачи. Вторая строка тут стоит по делу: если ссылка вернула пустой ответ или страницу с ошибкой, число строк это сразу покажет, и прогон не стартует на пустом списке. Я добавляю простую проверку: файл короче ста строк считается негодным, и скрипт оставляет предыдущий вариант.
Ещё один момент про ссылку. Она отдаёт текст, значит её содержимое можно направить прямо в программу, минуя диск. У части парсеров есть поле для адреса списка, куда ссылка вставляется целиком, и софт сам ходит за обновлением по своему расписанию. Такой вариант я предпочитаю всему остальному: одна настройка закрывает сразу и задание в планировщике, и файл на диске. Трафик за такие обращения не считается никак, безлимит по объёму в любом пакете снимает вопрос о частоте обновления полностью.
Форматы под разные программы: расширение и антидетект-браузер
Софт делится на четыре группы по тому, как он принимает адрес. Понимание группы экономит время: становится ясно, какой из двух форматов брать и в каком виде подавать выдачу.
| Тип программы | Какой формат принимает | Как подаётся | На что смотреть |
|---|---|---|---|
| Расширение браузера | Поля по отдельности | Адрес, порт, имя, пароль руками | Схема выбирается списком, не текстом |
| Антидетект-браузер | Строка целиком | Вставка в поле или импорт файлом | Разделитель полей задаётся настройкой |
| Парсер со своим менеджером | Файл или ссылка | Загрузка списка целиком | Порядок полей выбирается шаблоном |
| Код и командная строка | Строка со схемой | Сборка из полей внутри программы | Спецсимволы в пароле кодируются |
Две первые группы разбираю прямо здесь, две оставшиеся в следующем разделе.
Расширение браузера принимает поля по одному. Тут длинный формат приходится разбирать глазами: адрес в первое поле, порт во второе, имя в третье, пароль в четвёртое. Самая частая ошибка выглядит как вставка 203.0.113.24:8080 целиком в поле адреса. Расширение примет строку молча, порт возьмёт из своего значения по умолчанию, и браузер пойдёт мимо пула. Признак у этого один: страница открывается, а сервис проверки показывает адрес вашего канала. Поле адреса принимает только адрес.
Схема в расширении выбирается отдельным переключателем со значениями HTTP и SOCKS5. Переключатель нужно менять вместе с портом. Я видел десяток случаев, когда человек менял порт с HTTP на SOCKS5 и забывал переключатель, после чего решал, что узел нерабочий.
Антидетект-браузер удобнее: он принимает строку целиком и разбирает её сам. В настройках профиля обычно есть выбор порядка полей, потому что часть поставщиков отдаёт список в перевёрнутом виде, с именем и паролем впереди адреса. Порядок нужно выставить один раз под свою выдачу и дальше не трогать. Массовый импорт из файла раскладывает строки по профилям по очереди, одна строка на профиль, и это самый быстрый путь развернуть несколько десятков профилей за раз. Под такой сценарий я готовлю прокси под антидетект-браузер заранее и слежу, чтобы число строк в файле совпадало с числом профилей.
Проверка после импорта занимает минуту и делается встроенным чекером профиля. Он показывает адрес и отклик по каждому профилю списком. Если у части профилей поле пустое, значит файл содержал меньше строк, чем нужно, и хвост профилей остался без адресов.
Парсер со своим менеджером списка и подстановка из кода
У серьёзных парсеров есть свой менеджер прокси, и он ждёт список файлом или ссылкой. Формат там задаётся шаблоном: программа спрашивает, что стоит на первой позиции, что на второй, какой символ служит разделителем. Шаблон выставляется один раз под выдачу поставщика. После этого файл грузится целиком, и менеджер сам раздаёт строки потокам, помечая нерабочие.
Важная настройка в таких менеджерах называется по-разному, смысл у неё один: сколько потоков разрешено пускать через одну строку списка. Я ставлю единицу, когда прогон идёт по площадке с жёстким счётом обращений с адреса, и три, когда счёт мягкий. Общий предел по пакету при этом остаётся своим, до 1000 потоков на обычных пакетах и до 3000 на корпоративном, и превысить его настройкой парсера нельзя.
В коде список читается построчно и превращается в очередь. Разбор я показал выше, дальше строка собирается в полную запись со схемой. Кодирование спецсимволов в пароле обязательно: символ собаки внутри пароля разорвёт строку по неверному месту, потому что клиент ищет последнее вхождение собаки как границу.
from urllib.parse import quote
def to_url(p, scheme="socks5h"):
if "user" in p:
u, w = quote(p["user"], safe=""), quote(p["pwd"], safe="")
return f"{scheme}://{u}:{w}@{p['host']}:{p['port']}"
return f"{scheme}://{p['host']}:{p['port']}"
Функция короткая и закрывает оба формата сразу. Строка без имени и пароля соберётся в вид socks5h://203.0.113.24:1080, и такой конфиг корректен при работе через привязанный адрес.
Пять причин сорванной загрузки списка
Собрал статистику по своим разборам: 60 обращений подряд, где список не завёлся с первого раза. Ни один из случаев не относился к самому пулу, все пять причин сидели в тексте файла.
Пробелы по краям строк дали 19 случаев из 60. Появляются они при копировании из мессенджера, из таблицы, из письма. Программа берёт строку целиком вместе с пробелом, пытается превратить 203.0.113.24 в адрес и получает отказ. Лечится обрезкой краёв у каждой строки, в коде это strip, в редакторе замена по регулярному выражению.
Порт в поле адреса дал 14 случаев. Разобрал выше на примере расширения, добавлю только, что та же ошибка встречается в конфигах systemd и в переменных окружения, где адрес и порт положено разносить.
Перенос строк в стиле CRLF дал 12 случаев. Файл, сохранённый в Windows, несёт в конце каждой строки два символа, и на Linux второй из них остаётся хвостом в последнем поле. Пароль превращается в k39dhzp\r, допуск отклоняется, адрес при этом верный. Диагностируется мгновенно: если в логе видно отказ по паролю на всех строках сразу, смотрите переносы. Команда file list.txt покажет тип переносов, dos2unix их поправит.
Кодировка с меткой BOM дала 9 случаев. Метка невидима в редакторе и сидит в самом начале файла, поэтому портится ровно одна строка, первая. Программа отбрасывает её как битую и молча работает с остальными, а вы считаете, что загрузился весь список. Сохраняйте файл в UTF-8 без метки.
Пустая строка в конце файла дала 6 случаев. Некоторые менеджеры считают её записью и добавляют в пул пустой узел, после чего каждый N-й запрос уходит в никуда. Проверка на пустоту в парсере строк закрывает этот случай навсегда.
Как проверить строку до загрузки в софт
Порядок у меня одинаковый для любой программы, и занимает он меньше минуты. Сначала одна строка проверяется вручную через curl, и только потом список едет в софт целиком. Смысл в том, чтобы отделить проблему текста от проблемы настроек программы.
head -n1 list.txt | tr -d '\r' | awk -F: '{print "socks5h://"$3":"$4"@"$1":"$2}'
Команда берёт первую строку списка, срезает хвост переноса и собирает готовую строку подключения. Её остаётся подставить в curl и посмотреть ответ сервиса эха. Пришёл адрес узла пула значит формат разобран верно, и дальше можно грузить весь файл.
Массовую проверку я делаю тем же скриптом по всему списку, с ограничением по времени ответа. Пять секунд на попытку хватает: узел, который не ответил за это время, я в прогон не беру.
while IFS=: read -r ip port user pwd; do
out=$(curl -s -m 5 -x "socks5h://$user:$pwd@$ip:$port" https://api.ipify.org)
echo "$ip:$port $out"
done < <(tr -d '\r' < list.txt)
Вывод пишется в файл и просматривается глазами за полминуты. Строки с пустым вторым полем это отказ, их я откладываю и перепроверяю через несколько минут: ротация внутри пула идёт постоянно, и через проход состав отвечающих узлов меняется. Отдельно советую держать в кабинете тестовый прогон перед покупкой, бесплатный тест до 2 часов как раз позволяет проверить формат под свой софт до оплаты.
Как обновлять список без остановки работы
Обновление списка на работающем прогоне выглядит страшнее, чем оно есть. Схема, которую я использую на всех своих парках, состоит из трёх шагов и не требует перезапуска.
Первый шаг: свежая выдача скачивается во временный файл. Второй шаг: временный файл проверяется на длину и на разбор первой строки. Третий шаг: файл переименовывается поверх рабочего, и это действие атомарно в пределах одной файловой системы. Программа, которая читает список по расписанию, подхватит новый вариант при следующем чтении и никогда не увидит наполовину записанный файл.
curl -s "$LIST_URL" -o /opt/pool/.new
[ $(wc -l < /opt/pool/.new) -ge 100 ] && mv /opt/pool/.new /opt/pool/list.txt
Для софта со своим менеджером порядок другой: там обновление вызывается кнопкой или по таймеру самой программы, и трогать файл на диске незачем. Я выставляю таймер на час и не вмешиваюсь. Для кода живее всего работает вариант с очередью: скрипт перечитывает список раз в несколько минут, добавляет новые строки в конец очереди и убирает те, что перестали отвечать. Прогон при этом идёт без пауз.
Когда список нужен на нескольких машинах, я забираю его один раз на управляющем узле и раздаю оттуда. Так все машины работают от одинакового набора строк, и разбор проблем сильно упрощается. Для веб-прогонов на этих машинах я держу приватные HTTP-адреса под загрузку списком, а порт SOCKS5 подставляю из того же файла второму классу задач.
Соседние материалы вики по теме: прокси для досок объявлений разбирают работу с профилями площадок, сбор отзывов и репутации бренда показывает прогоны по карточкам, лимит потоков и расчёт нагрузки объясняет, как разложить пакет по задачам, а порт прокси-сервера подробно разбирает второе поле строки и его значения по протоколам.