«Прокси», «Список прокси» — такой частый запрос в 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)