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

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

«Прокси», «Список прокси» — такой частый запрос в Google, что я (в учебных, понятное дело) целях задался целью сделать парсер прокси-серверов на Python. И оказывается (впрочем, как всегда) — все проще, чем кажется 🙂 Итак, поехали!

Одним из ведущих по моему мнению ресурсов, занимающихся составлением списка работающих прокси-серверов является сайт Hidemy.name, которые так же занимаются предоставлением VPN (зачем это нужно — читайте тут) — а значит, будем парсить список прокси с их сайта, благо — обновляется этот список каждые две-три минуты 🙂 Наша цель: получение списка прокси-серверов, выгрузка в файлик, и радость в итоге.

Приступим:
1. Нам нужно получить исходный код страницы, на которой расположены актуальные прокси и информация о портах соединения
2. Получаем адреса прокси-серверов
3. Получаем порты
4. Все сливаем в файлик.

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

import requests #подключаем библиотеку, которая ЗНАЧИТЕЛЬНО упрощает работу с http-запросами
from fake_useragent import UserAgent #библиотека для генерации поддельного запроса на сервер (позволяет создавать поддельные заголовки пакетов, благодаря чему сайт «видит» якобы реального человека
from bs4 import BeautifulSoup #библиотека, помогающая в обработке получаемых данных
import re #библиотека, служащая для парсинга информации
link_to_proxylist = ‘https://hidemy.name/ru/proxy-list/
#Загоняем в переменную ссылку на страницу с адресами-портами прокси-серверов
response = requests.get(link_to_proxylist, headers={‘User-Agent’: UserAgent().chrome})
#Загоняем в переменную ответ, который получаем от указанного адреса, причем — запрос отправляем прикрывшись поддельным заголовком (якобы, реальный человек)
html = requests.get(link_to_proxylist) #По указанному запросу запрашиваем содержимое страницы
html = response.content #Загоняем в переменную содержимое страницы

Итак, к настоящему моменту мы:

  • Прикрылись поддельным заголовком
  • Получили полный текст страницы
  • Следующий пункт нашей программы — обработка полученной информации:
    soup = BeautifulSoup(html,’html.parser’) #Подключаем ПрекрасныйСуп, показываем, что именно нужно парсить
    proxy_server = soup.findAll(‘td’, attrs = {‘class’:’tdl’}) #Загоняем в переменную все, что находится на указанной странице между тегами td и class = ‘tdl’ (исходный код страницы доступен по ссылке).
    Почему именно то, что между указанных тегов? Да просто именно там хранятся адреса серверов:

    hideme - где прячутся адреса прокси
    Для увеличения — кликните по картинке

    Теперьу нас имеется список с адресами прокси-серверов, которые завернуты в теги < td> и < /tdl>. Постараемся очистить этот бардак с помощью регулярного выражения (ПрекрасныйСуп тут уже, к сожалению, не особо помощник):
    proxy_server = str(proxy_server) #Так как регулярные выражения работают по строковым типам — конвертируем переменную, в которой у нас имеется список прокси-серверов в строковый тип
    regxp = ‘>(.*?)< /td>‘ #Указываем в регулярном выражении, что именно ищем: все, что находится между тегами > и < /td>
    result_proxy = re.findall(regxp, proxy_server) #Загоняем в переменную все, что получается с помощью регулярного выражения regxp, которое применяется к переменной proxy_server

    В итоге получаем переменную result_xp, в которой содержится список прокси-серверов в чистом виде. Теперь получим порты, по которым нужно соединяться с прокси-серверами:
    html = str(html) #конвертируем переменную html (исходный код страницы) в строковую, что бы иметь возможность использовать регулярное выражение
    regxp = ‘>(\d+)<' #Задаем регулярное выражение, которое будет выгребать все цифры, заключенные между знаками > и <.
    result_ip = re.findall(regxp, html) #Загоняем в переменную result_ip все, что получается в результате работы регулярного выражения применительно к переменной html

    Наверное, все хорошо, только … регулярка сгребает еще ряд цифр, которые проходят по показателям (номера страниц), но нам совершенно не нужны, ведь мы работаем только по первой странице, где есть самые актуальные прокси-сервера. Обрезаем их просто — по количеству прокси-серверов в переменной result_proxy (логика простая: количество серверов должно совпадать с количеством портов):

    del result_ip[len(result_proxy):] #т.е. обрезаем список result_ip до количества значений, равного списку result_proxy, благодаря чему получаем переменную result_ip, содержащую количество портов равное количеству серверов в переменной result_proxy.

    А теперь осталось записать в файлик все, что получилось. Для этого используем код:
    i = 0 #Вводим в код переменную i — ее будем использовать в цикле записи
    while i < len(result_proxy): #объявляем цикл, работающий до момента, пока переменная i не станет больше количества прокси-серверов в переменной result_proxy
    ip_port = (result_proxy[0], ‘:’, result_ip[0]) #создаем переменную ip_port, которая формируется за счет объединения адреса прокси-сервера (список result_proxy, нулевое значение) и номер порта прокси-сервера (список result_ip, нулевое значение)
    del result_proxy[0] #удаляем нулевое значение в списке прокси-серверов
    del result_ip[0] #удаляем нулевое значение в списке портов
    ip_port = ».join(ip_port) #корректируем получившееся значение — убираем пробелы
    print(ip_port) #выводим получившееся значение на экран (можно и без этого 🙂 )
    i = i + 1 #увеличиваем значение i на единицу

    with open(‘proxy_list.txt’, ‘a’, encoding=’utf8′) as f: #открываем для записи файл proxy_list.txt. В случае, если он отсутствует — файл создается

    f.write(ip_port + ‘\n’) #записываем в файл переменную ip_port, содержащую в себе адрес сервера и номер порта для соединения и символ \n — для обозначения перехода на следующую строку
    print(‘Файл сохранен.’) #в конце работы выводим сообщение о окончании подготовки файла со списком прокси-серверов

    В полном виде код доступен по ссылке.

    Конечно же — в случае возникновения вопросов — пожалуйста, пишите.

    UPD: чуть переделал код. Теперь у нас происходит сортировка прокси по скорости (не более 500 мс) и типу (HTTP). Сам код выглядит так:

    1. print('Открываем сайт для получения списка прокси... \n')
    2. browser = webdriver.Chrome()
    3. browser.get('https://hidemy.name/ru/proxy-list/')
    4.  
    5. time.sleep(15)
    6. browser.find_element_by_xpath(".//*[contains(text(),'HTTP')]").click() #Выбрали http-прокси
    7.  
    8. time.sleep(5)
    9. browser.find_element_by_id('maxtime').send_keys('500') #Установили скорость прокси для фильтра
    10.  
    11. time.sleep(5)
    12. browser.find_element_by_xpath("//a[@class='button button_green ']").click()
    13.  
    14. time.sleep(10)
    15. print('Получаем исходный код страницы... \n')
    16. html = browser.page_source
    17. print('Исходный код страницы:\n', html)
    18.  
    19. soup = BeautifulSoup(html,'html.parser') #Подключаем Суп, парсим полностью код страницы
    20. proxy_server = soup.findAll('td', attrs = {'class':'tdl'})
    21.  
    22. #Начинаем парсить адреса прокси-серверов
    23. proxy_server = str(proxy_server)
    24. regxp = '>(.*?)</td>'
    25. result_proxy = re.findall(regxp, proxy_server)
    26. print(result_proxy)
    27. print(len(result_proxy))
    28.  
    29. #Начинаем парсить номера портов
    30. html = str(html)
    31. regxp = '>(\d+)<'
    32. result_ip = re.findall(regxp, html)
    33.  
    34. #Обрезаем лишнее
    35. del result_ip[len(result_proxy):]
    36. i = 0
    37. print('Список прокси:\n')
    38. proxy_list = []
    39. while i < len(result_proxy):
    40.     ip_port = (result_proxy[0], ':', result_ip[0])
    41.     del result_proxy[0]
    42.     del result_ip[0]
    43.     ip_port = ''.join(ip_port)
    44.     print(ip_port)
    45.     i = i + 1
    46.     with open('proxy_list.txt', 'a', encoding='utf8') as f:
    47.         f.write(ip_port + '\n')
    48.     proxy_list.append(ip_port)
    49.  
    50. print('Имеем', len(proxy_list), 'прокси')
    51. print('Файл с прокси-серверами сохранен!\n')
    52. random_proxy = proxy_list[random.randrange(0, len(proxy_list))]
    53.  
    54. print('Выбрали прокси:', random_proxy)