Списки прокси

Что такое прокси. Для чего нужны прокси

Прокси — это обобщённое название технологий, главный результат которых в том, что запрос к удалённому хосту для вас делает другой компьютер, а потом присылает вам результат. То есть прокси — это посредник.

Прокси имеют различные применения, среди них: анонимизация (сокрытие реального IP), обход ограничений (доступа из определённых стран или по количеству запросов), увеличение производительности (например, за счёт кэширования передаваемых данных) и другие случаи использования.

Поскольку в этой статье я буду рассматривать публичные (бесплатные) прокси, то я бы не советовал их использовать для анонимизации — среди них могут быть Honeypot. Либо они могут быть настроены так, что фактически всё равно передают в заголовках протокола ваш реальный IP.

То есть, например, для обхода ограничений в некритичных ситуациях публичные прокси подойдут, а для чего-то более серьёзного, следует использовать другие варианты. И без необходимости я бы тоже не рекомендовал использовать прокси — мы не знаем, с какой целью они созданы и что делает владелец прокси с передаваемыми данными.

Бесплатные прокси

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

  • страна
  • протокол прокси
  • доступность
  • скорость соединения
  • время отклика

Некоторые сайты со списками прокси довольно дружественны к пользователю и даже позволяют скачать списки в виде текстового файла или в табличном виде. Некоторые напротив — используют техники обфускации чтобы затруднить парсинг списков.

В этой заметке я покажу, как можно парсить IP с номерами портов и сохранять их в текстовый файл. Я покажу как это делать в командной строке с использованием программирования. Также приведу пример кода в котором показывается, как использовать эти списки в своей программе.

Если вам не хочется возиться с командной строкой, но хочется получать такие списки в один столбик (удобно для импорта в программы), то я создал специальный сервис — на котором вы сможете скачать списки прокси — в один столбик и без лишних данных.

Как парсить списки прокси

Если вам хочется научиться писать свои собственные парсеры для разных сайтов, в том числе со списками прокси, то смотрите эти статьи:

Прокси с сайта hidemyna.me

Я рассмотрю несколько сайтов — их я нашёл через Google — взял первые попавшиеся сайты на первой и второй страницах результатов поиска. То есть ничего про качество прокси я сказать не могу — это не какие-то отобранные и хорошие списки — это просто первые попавшиеся сайты. И первый из них — hidemyna.me.

Списки по различным критериям доступны по адресу: https://hidemyna.me/ru/proxy-list/

Я буду писать код на PHP — удобно использовать не только в командной строке, но также и закидывать на веб-сервер. Если в качества языка для написания скриптов вы предпочитаете Bash, то рекомендуется изучить регулярные выражения команды grep: «Регулярные выражения и команда grep».

Для сбора прокси в формате IP:ПОРТ создайте файл proxy_parser.php и скопируйте в него:

<?php

$link = 'https://free-proxy-list.net/';

$agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36';

$ch = curl_init($link);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response_data = curl_exec($ch);
if (curl_errno($ch) > 0) {
    die('Ошибка curl: ' . curl_error($ch));
}
curl_close($ch);

preg_match_all('#<td>[0-9.]{5,}[0-9]{2,}</td>#', $response_data, $rawlist);

$cleanedList = str_replace('</td><td>', ':', $rawlist[0]);
$cleanedList = str_replace('<td>', '', $cleanedList);
$cleanedList = str_replace('</td>', '', $cleanedList);

foreach ($cleanedList as $key => $value) {
    echo $value . PHP_EOL;
}

Запускать так:

php proxy_parser.php

Будет получен список из 300 прокси:

Также обратите внимание, что в массив $cleanedList скопированы эти же прокси — на тот случай, если понадобится использовать их прямо в программе (пример ниже).

Как я уже сказал, если вам не хочется возиться с командной строкой, всегда актуальный список прокси с сайта hidemyna.me на этой странице: https://suip.biz/ru/?act=proxy1

Прокси с сайта spys.one

Следующий сайт — spys.one. На нём списки сгруппированы по разным критериям. Если вас интересуют определённые страны, то последующий код парсинга отредактируйте под свои нужды (скорее всего, достаточно просто поменять адрес страницы). Меня интересуют все прокси подряд из любой страны с любыми характеристиками, поэтому я буду парсить страницу http://spys.one/en/free-proxy-list/.

Особенности этого сайта в том, что номера портов в исходном коде записаны в обфусцированном виде (нечитаемом для большинства инструментов командной строки). Ещё одна особенность — по умолчанию на одной странице показывается только 30 адресов. Можно вывести максимум 500, но для этого к странице нужно отправить соответствующий POST запрос.

Для решения проблемы с обфускацией я буду использовать PhantomJS. Дополнительные подробности вы сможете найти в статьях:

Для получения списка из 500 прокси создайте файл proxy_parser.js со следующим содержимым:


"use strict";
var page = require('webpage').create(),
        server = 'http://spys.one/en/free-proxy-list/',
        data = 'xpp=5&xf1=0&xf2=0&xf4=0&xf5=0';

page.open(server, 'post', data, function (status) {
    if (status !== 'success') {
        console.log('Unable to post!');
    } else {
        console.log(page.plainText);
    }
    phantom.exit();
});

Запустите его так:

phantomjs proxy_parser.js | grep -E -o '[0-9.]{7,}:[0-9]{2,}'

Будет получен очищенный список прокси:

Опять же, если вам не хочется возиться с командной строкой и/или устанавливать PhantomJS, то всегда свежий список прокси, полученный описанным методом, вы найдёте на странице: https://suip.biz/ru/?act=proxy2

Прокси с сайта gatherproxy.com

На сайте http://www.gatherproxy.com/ мы опять сталкиваемся с обфускацией — номера портов в шестнадцатеричном формате. Проблема решается с помощью PHP функции hexdec.

Создадим файл proxy_parser2.php и скопируем в него:

<?php

$link = 'http://www.gatherproxy.com/';

$agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36';

$ch = curl_init($link);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response_data = curl_exec($ch);
if (curl_errno($ch) > 0) {
    die('Ошибка curl: ' . curl_error($ch));
}
curl_close($ch);

preg_match_all('#"PROXY_IP":"([0-9.]+)","PROXY_LAST_UPDATE":"[0-9. ]+","PROXY_PORT":"([A-Za-z0-9.]+)"#', $response_data, $rawlist);

foreach ($rawlist[1] as $key => $value) {
    echo $value . ":" . hexdec($rawlist[2][$key]) . PHP_EOL;
}

Для фильтрации прокси запустим его:

php proxy_parser2.php

Опять же, если у вас Windows, то готовый список вы найдёте здесь: https://suip.biz/ru/?act=proxy3

Сайты с прокси, которые позволяют скачать списки

На некоторых сайтах списки прокси уже в удобном формате без всего лишнего. Пример такого сайта:

Как использовать прокси в своей программе (на примере PHP)

Далее показан пример кода на PHP, который парсит список прокси, а затем запускает программу используя полученные значения. Если результат не получен (не важно по каким причинам — не рабочий прокси или удалённый хост забанил адрес этого прокси), то выполняется переход к следующей паре IP:ПОРТ и заново делается запрос к удалённому хосту. Если опять неудача — то всё повторяется заново, пока не будет получен нужный результат.

Если все адреса прокси кончаются, то парсится новый список.

Код:

<?php

//Устанавливаем счётчик списка прокси на 0
$proxy_counter = 0;

//Функция парсинга списка прокси
function getProxy() {
    global $proxy_counter;

    $link = 'https://free-proxy-list.net/';

    $agent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36';

    $ch = curl_init($link);
    curl_setopt($ch, CURLOPT_USERAGENT, $agent);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response_data = curl_exec($ch);
    if (curl_errno($ch) > 0) {
        die('Ошибка curl: ' . curl_error($ch));
    }
    curl_close($ch);

    preg_match_all('#<td>[0-9.]{5,}[0-9]{2,}</td>#', $response_data, $rawlist);

    $cleanedList = str_replace('</td><td>', ':', $rawlist[0]);
    $cleanedList = str_replace('<td>', '', $cleanedList);
    $cleanedList = str_replace('</td>', '', $cleanedList);

    //Сбрасываем счётчик если это уже не первый список прокси
    $proxy_counter = 0;
    //Докладываем, что список составлен
    echo 'Составили новый список прокси' . PHP_EOL . PHP_EOL;
    //Возвращаем спарсеный список
    return $cleanedList;
}

//Получаем начальный список из 300 прокси
$proxy = getProxy();

//Функция, в которой вызывается некая программа, использующая прокси
function doIt($url) {
    // Эти переменные должны быть в области видимости функции
    global $proxy;
    global $proxy_counter;

    //Некая команда, которая использует прокси - в данном случае для примера взята cURL с опцией --proxy
    //При этом $proxy[$proxy_counter] на начальном этапе соответствует $proxy[0], то есть
    //первой паре IP:ПОРТ
    $command = "curl --proxy $proxy[$proxy_counter] $url";
    
    //Отправляем системе команду для выполнения
    //Вывод функции сохраняется в массив $output
    exec($command, $output);
    
    //Если результат получен и вывод функции не является пустым, то эта секция пропускается
    if (empty($output[0])) {
        do {
            //Если результат не получен, то попадаем сюда
            //Переходим к следующему в списке прокси
            $proxy_counter++;
            //Заново собираем команду с уже новым прокси
            $command = "curl --proxy $proxy[$proxy_counter] $url";
            //Отправляем на выполнение
            exec($command, $output);
            //Кстати, у нас всего 300 прокси, поэтому если мы достигли последнего значения,
            //то пересоздаём список (парсим новые прокси)
            if ($proxy_counter == 299) {
                $proxy = getProxy();
            }
        //При работе функции результаты сохраняются в последующие элементы массива,
        //то есть в $output[1], $output[2], $output[3] и так далее.
        //Мы проверяем, не является ли пустым самый последний элемент массива
        //который содержит результат последнего запуска функции
        //Если результат является пустым, то заходим на новый круг.
        } while (empty(end(array_values($output))));
    }
    //Как только результат работы программы не является пустым, эта функция
    //возвращает значение и завершает работу
    return end(array_values($output));
}

//Вызов функции
doIt('https://site.ru');

В логике программы заложено использовать рабочий прокси пока он не будет забанен удалённым хостом. Я экспериментировал: делал каждый новый запрос с новым прокси (чтобы оттянуть блокировку по IP), но результаты для моих целей оказались намного хуже. Тем не менее, если у вас качественный список прокси, большая часть которых не забанена на удалённом хосте, то можно делать каждый новый запрос с новым прокси. Для этого сразу после первого вызова:

    exec($command, $output);

Добавьте строки:

            $proxy_counter++;
            if ($proxy_counter == 299) {
                $proxy = getProxy();
            }

То есть будет происходить смена прокси даже если запрос прошёл удачно.

Заключение

Пожалуй, мне уже хватит прокси. Если вы хотите поделиться другими сайтами с хорошими списками прокси, то пишите их в комментариях. Если вам хочется, чтобы я рассмотрел как их парсить и добавил очищенные списки на SuIP.biz, то указывайте это.

Кстати, про прокси мы ещё не закончили — в одной из следующих статей я покажу, как виртуальный хостинг превратить в свой собственный прокси сервер.

Вы уже знаете о факультете информационной безопасности от GeekBrains? Комплексная годовая программа практического обучения с охватом всех основных тем, а также с дополнительными курсами в подарок. По итогам обучения выдаётся свидетельство установленного образца и сертификат. По этой ссылке специальная скидка на любые факультеты и курсы!

Рекомендуется Вам:

Добавить комментарий

Ваш e-mail не будет опубликован.