Парсинг сайта с прокси на Python 3 + BS4
Начнём с зависимостей.
import requests from bs4 import BeautifulSoup
Установка BeautifulSoup была в прошлом уроке, так что объяснять повторно не буду. Грабить прокси мы будем с этого сайта: http://foxtools.ru/Proxy
Прокси расположены в таблицах (td), а точнее в 2х таблицах с разными стилями, отсюда и небольшой костыль. Код я обернул в функцию которая возвращает массив с прокси вида: "192.168.4.4:8080". И так, ниже я кину полную функцию и после буду объяснять что да как.
def proxy_grab(): proxy = [] for m in range(int(soup.find_all("div", {"class": "pager"})[-1].find_all("a")[-1].contents[0]) + 1): rer = requests.get("http://foxtools.ru/Proxy?page=" + str(m)) soup2 = BeautifulSoup(rer.text, 'html.parser') for i in range(len(soup2.find_all('tr', {"class": "alt"}))): table = soup2.find_all('tr', {"class": "alt"})[i] ip = table.find_all('td')[1].contents[0] port = table.find_all('td')[2].contents[0] table2 = soup2.find_all('tr', {"class": ""})[i + 1] ip2 = table2.find_all('td')[1].contents[0] port2 = table2.find_all('td')[2].contents[0] proxy.append(str(ip) + ":" + str(port)) proxy.append(str(ip2) + ":" + str(port2)) return proxy
Для начала нам надо узнать сколько есть страниц на сайте. У нас 6 страниц, полный список страниц предоставлен в элементе :
soup.find_all("div", {"class": "pager"})[-1].find_all("a")[-1].contents[0]
Отсюда мы получаем число страниц. Оно будет как строка, поэтому мы преобразуем его в int и прибавим 1 ибо цикл будет идти до 5 потому что начинается с 0, но добавив единицу мы получим цикл до последней - 6 страницы.
Далее, в цикле мы переходим на страницу, например один, далее создаём объект супа с этой страницей, и уже в длине массива со всеми таблицами вытаскиваем с таблиц айпи и порт. У нас 2 класса таблиц, одна с пустым классом, другая с классом alt : soup2.find_all('tr', {"class": "alt"}) , soup2.find_all('tr', {"class": ""}).
Как можно заметить у второй таблицы "table2" в конце есть приписка [i + 1] это потому что нулевая таблица у нас это не таблица с ip и port, это название таблиц, сейчас покажу в скрине.
Вот это нулевой элемент, поэтому мы прибавляем к нему единицу что бы получать айпи и порт. Если же вам не надо добавлять всех в массив и вы хотите видеть просто вывод то ниже будет код который будет выдавать инфу по айпи, порту, страна, скорость, тип прокси и когда был прочекан.
for m in range(int(soup.find_all("div", {"class": "pager"})[-1].find_all("a")[-1].contents[0]) + 1): rer = requests.get("http://foxtools.ru/Proxy?page=" + str(m)) soup2 = BeautifulSoup(rer.text, 'html.parser') for i in range(len(soup2.find_all('tr', {"class": "alt"}))): table = soup2.find_all('tr', {"class": "alt"})[i] ip = table.find_all('td')[1].contents[0] port = table.find_all('td')[2].contents[0] country = table.find_all('td')[3].contents[-1] speed = table.find_all('td')[4].contents[-1] type_proxy = table.find_all('td')[5].contents[-1] status_check = table.find_all('td')[7].contents[-1] print("Айпи: " + ip + "\n" + "Порт: " + port + "\n" + "Страна: " + re.sub(r'\s+', ' ', country)[1:] + '\n' + "Скорость: " + re.sub(r'\s+', ' ', speed)[1:] + '\n' + "Тип прокси: " + re.sub(r'\s+', ' ', type_proxy)[1:] + '\n' + "Время проверки: " + status_check + '\n' + "________________________________________") table2 = soup2.find_all('tr', {"class": ""})[i + 1] ip2 = table2.find_all('td')[1].contents[0] port2 = table2.find_all('td')[2].contents[0] country2 = table2.find_all('td')[3].contents[-1] speed2 = table2.find_all('td')[4].contents[-1] type_proxy2 = table2.find_all('td')[5].contents[-1] status_check2 = table2.find_all('td')[7].contents[-1] print("Айпи: " + ip2 + "\n" + "Порт: " + port2 + "\n" + "Страна: " + re.sub(r'\s+', ' ', country2)[1:] + '\n' + "Скорость: " + re.sub(r'\s+', ' ', speed2)[1:] + '\n' + "Тип прокси: " + re.sub(r'\s+', ' ', type_proxy2)[1:] + '\n' + "Время проверки: " + status_check2 + '\n' + "_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_+_")
Вот это выдаст вам в вашу консоль всё необходимое. Скрин ниже:
Теперь же нам надо прочекать прокси, у меня это вышло не очень хорошо и вообще не советую использовать этот код. Вышло вот так:
def proxy_check(proxy_list): f = open("proxy_good.txt", "a") for proxy in proxy_list: try: rwww = requests.get("http://myip.ru", timeout=2, proxies={"http": proxy}) if rwww.status_code == 200: print("[+] " + proxy + " [+]") f.write(proxy + '\n') else: pass except: print("[-][-][-][-] " + proxy + " [-][-][-][-]")
Мы создали функцию которая принимает в себя массив с прокси вида "192.168.4.4:8080" то есть айпи:порт. С помощью цикла мы пробуем подключиться к каждому прокси с таймаутом в 2 секунды. Таймаут можете подбирать по своему усмотрению. Из 160 прокси гудов было 20, но это при таймауте в 2 секунды. Так же все гуд прокси записываются в файл и выводятся в консоль.
Вызывать функцию мы может вот так:
proxy_check(proxy_grab())
А теперь подарочек. Есть репозиторий который грабит прокси : https://github.com/constverum/ProxyBroker
И я немного посмотрев примеры успешно позаимствовал немного примеров. И так, мы имеем:
import asyncio from proxybroker import Broker async def show(proxies): f = open("test_proxy.txt", 'a') while True: proxy = await proxies.get() if proxy is None: break proto = 'https' if 'HTTPS' in proxy.types else 'http' f.write(proxy.host + ":" + str(proxy.port) + "\n") proxies = asyncio.Queue() broker = Broker(proxies) tasks = asyncio.gather( broker.find(types=['HTTP', 'HTTPS']), show(proxies)) loop = asyncio.get_event_loop() loop.run_until_complete(tasks)
Итак, мы имеем функцию которая записывает в файл гуды "Айпи:Порт"
Вам нужен только репозиторий proxybroker
pip install proxybroker
Далее можете вставить эту функцию в свою IDE или блокнот и запустить, после этого в директории со скриптом создастся текстовый файл в который будут записаны все прокси. Прокси можете чекать с помощью бесплатной утилиты "Elite Proxy Switcher"
https://www.eliteproxyswitcher.com
Ну мне по итогу выбило ошибку после 1500 прокси, но это не важно, мы получили прокси и вот результат чека с помощью софта выше:
А теперь весь листинг программы которая была написана мной. Там результаты не такие радужные как у прокси грабера который был позаимствован с либы ProxyBroker).
def proxy_grab(): proxy = [] for m in range(int(soup.find_all("div", {"class": "pager"})[-1].find_all("a")[-1].contents[0]) + 1): rer = requests.get("http://foxtools.ru/Proxy?page=" + str(m)) soup2 = BeautifulSoup(rer.text, 'html.parser') for i in range(len(soup2.find_all('tr', {"class": "alt"}))): table = soup2.find_all('tr', {"class": "alt"})[i] ip = table.find_all('td')[1].contents[0] port = table.find_all('td')[2].contents[0] table2 = soup2.find_all('tr', {"class": ""})[i + 1] ip2 = table2.find_all('td')[1].contents[0] port2 = table2.find_all('td')[2].contents[0] proxy.append(str(ip) + ":" + str(port)) proxy.append(str(ip2) + ":" + str(port2)) return proxy def proxy_check(proxy_list): f = open("proxy_good.txt", "a") for proxy in proxy_list: try: rwww = requests.get("http://myip.ru", timeout=2, proxies={"http": proxy}) if rwww.status_code == 200: print("[+] " + proxy + " [+]") f.write(proxy + '\n') else: pass except: print("[-][-][-][-] " + proxy + " [-][-][-][-]") proxy_check(proxy_grab())
Мой код не идеален. Вы всегда можете его модифицировать и использовать в своих целях. Да и вообще, я пишу ток костыли.