«Прокси», «Список прокси» — такой частый запрос в 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’ (исходный код страницы доступен по ссылке).
Почему именно то, что между указанных тегов? Да просто именно там хранятся адреса серверов:
Теперьу нас имеется список с адресами прокси-серверов, которые завернуты в теги < 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). Сам код выглядит так:
print('Открываем сайт для получения списка прокси... \n')
browser = webdriver.Chrome()
browser.get('https://hidemy.name/ru/proxy-list/')
time.sleep(15)
browser.find_element_by_xpath(".//*[contains(text(),'HTTP')]").click() #Выбрали http-прокси
time.sleep(5)
browser.find_element_by_id('maxtime').send_keys('500') #Установили скорость прокси для фильтра
time.sleep(5)
browser.find_element_by_xpath("//a[@class='button button_green ']").click()
time.sleep(10)
print('Получаем исходный код страницы... \n')
html = browser.page_source
print('Исходный код страницы:\n', html)
soup = BeautifulSoup(html,'html.parser') #Подключаем Суп, парсим полностью код страницы
proxy_server = soup.findAll('td', attrs = {'class':'tdl'})
#Начинаем парсить адреса прокси-серверов
proxy_server = str(proxy_server)
regxp = '>(.*?)</td>'
result_proxy = re.findall(regxp, proxy_server)
print(result_proxy)
print(len(result_proxy))
#Начинаем парсить номера портов
html = str(html)
regxp = '>(\d+)<'
result_ip = re.findall(regxp, html)
#Обрезаем лишнее
del result_ip[len(result_proxy):]
i = 0
print('Список прокси:\n')
proxy_list = []
while i < len(result_proxy):
ip_port = (result_proxy[0], ':', result_ip[0])
del result_proxy[0]
del result_ip[0]
ip_port = ''.join(ip_port)
print(ip_port)
i = i + 1
with open('proxy_list.txt', 'a', encoding='utf8') as f:
f.write(ip_port + '\n')
proxy_list.append(ip_port)
print('Имеем', len(proxy_list), 'прокси')
print('Файл с прокси-серверами сохранен!\n')
random_proxy = proxy_list[random.randrange(0, len(proxy_list))]
print('Выбрали прокси:', random_proxy)