Статья Пишем парсер на Python - грабим Proxy ч.1

Приветствую тебя читатель!

Продолжение здесь: Пишем парсер на Python - грабим Proxy ч.2

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

proxy.jpg


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

Приступим:

Для начала мы накидаем такую конструкцию

Python:
import requests
from bs4 import BeautifulSoup


if __name__ == '__main__':
    main()

Модуль requests нужен для обращения к серверу, BeautifulSoup анализирует html код, и последняя запись это точка входа в главную функцию main() которую мы напишем в самом конце программы.

Далее создадим функцию get_html которая принимает аргумент site. Переменная r обращается к requests методом get и получает чтение site. Функция возвращает r выведенную в текст.

Python:
def get_html(site):
    r = requests.get(site)
    return r.text

Далее создаём вторую функцию get_page_data для получения данных со страницы html. Эти сырые данные попадают в переменную soup. Обрабатывает данные BeautifulSoup, принимая код html. И в качестве парсера указываем 'lxml.

Python:
def get_page_data(html):
    soup = BeautifulSoup(html, 'lxml')

Добывать прокси мы будем с поэтому заходим по этому адресу, открываем инструменты разработчика кнопкой F12. Удобнее всего, на мой взгляд реализовано в ГуглХром. Кому-то нравится в лисе, но это не так важно. Наша задача определить в исходном коде, где находятся нужные нам строки.

В исходнике мы видим что proxy заключены в таблицу, и у этой таблицы есть id 'theProxyList'

table.png


Внутри таблицы находится тег tbody

tboby.png


А внутри тега tbody есть теги tr при наведении на которые выделяется строка (линия) с нужными данными.

tr.png


Значит чтобы спарсить эту линию добавим в нашу функцию такую строку

Python:
line = soup.find('table', id='theProxyList').find('tbody').find_all('tr')
# Ищем с помощью find 'tbody' и с помощью find_all все 'tr'

Прекрасно, начало есть. Но это ещё не всё друзья, не так быстро дела делаются :)
В функцию get_page_data теперь добавим цикл, в котором мы будем обращаться по индексу к нужным данным. Дата и время проверки не будем парсить, так как это не такая нужная информация. Остальное преобразуем в текст с помощью text

Python:
for tr in line:
        td = tr.find_all('td')
        ip = td[1].text
        port = td[2].text
        country = td[3].text
        anonym = td[4].text
        types = td[5].text
        time = td[6].text

Теперь полученные данные запишем в словарь

Python:
       data = {'ip': ip,
                'Порт': port,
                'Страна': country,
                'Анонимность': anonym,
                'Тип': types,
                'Время отклика': time}

И выведем на печать print(data).

Осталось написать главную функцию, в ней мы принимаем url сайта, и по цепочке идёт обработка предыдущими функциями.


Python:
def main():
    url = 'http://foxtools.ru/Proxy'
    get_page_data(get_html(url))

Наконец-то запускаем скрипт и видим следующую картину:

tdd.png


Данные успешно спарсились, но картинка не такая как хотелось бы. Присутствует куча мусора в виде \xa0, \r\n, \r\n\t\t\t\t\t
Значит будем от него избавляться. С помощью replace удалим всё лишнее, и для этого поправим наш цикл


Python:
    for tr in line:
        td = tr.find_all('td')
        ip = td[1].text
        port = td[2].text
        country = td[3].text.replace('\xa0', '')
        anonym = td[4].text.replace('\r\n        ', '')
        types = td[5].text.replace('\r\n\t\t\t\t\t', '').replace('\r\n        ', '')
        time = td[6].text

Запускаем по новой - другое дело, уже всё читабельно.

tddd.png


Python:
import requests
from bs4 import BeautifulSoup


def get_html(site):
    r = requests.get(site)
    return r.text


def get_page_data(html):
    soup = BeautifulSoup(html, 'lxml')
    line = soup.find('table', id='theProxyList').find('tbody').find_all('tr')

    for tr in line:
        td = tr.find_all('td')
        ip = td[1].text
        port = td[2].text
        country = td[3].text.replace('\xa0', '')
        anonym = td[4].text.replace('\r\n        ', '')
        types = td[5].text.replace('\r\n\t\t\t\t\t', '').replace('\r\n        ', '')
        time = td[6].text

        data = {'ip': ip,
                'Порт': port,
                'Страна': country,
                'Анонимность': anonym,
                'Тип': types,
                'Время отклика': time}

        print(data)


def main():
    url = 'http://foxtools.ru/Proxy'
    get_page_data(get_html(url))


if __name__ == '__main__':
    main()


Ну вот мы и научились некоторым приёмам парсинга страниц. В следующей статье мы продолжим работать с этим парсером и добавим функционал.
До встречи! ;)
 
Последнее редактирование:
V

VPN

Приветствую тебя читатель!

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

Посмотреть вложение 22957

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

Приступим:

Для начала мы накидаем такую конструкцию

Python:
import requests
from bs4 import BeautifulSoup


if __name__ == '__main__':
    main()

Модуль requests нужен для обращения к серверу, BeautifulSoup анализирует html код, и последняя запись это точка входа в главную функцию main() которую мы напишем в самом конце программы.

Далее создадим функцию get_html которая принимает аргумент site. Переменная r обращается к requests методом get и получает чтение site. Функция возвращает r выведенную в текст.

Python:
def get_html(site):
    r = requests.get(site)
    return r.text

Далее создаём вторую функцию get_page_data для получения данных со страницы html. Эти сырые данные попадают в переменную soup. Обрабатывает данные BeautifulSoup, принимая код html. И в качестве парсера указываем 'lxml.

Python:
def get_page_data(html):
    soup = BeautifulSoup(html, 'lxml')

Добывать прокси мы будем с поэтому заходим по этому адресу, открываем инструменты разработчика кнопкой F12. Удобнее всего, на мой взгляд реализовано в ГуглХром. Кому-то нравится в лисе, но это не так важно. Наша задача определить в исходном коде, где находятся нужные нам строки.

В исходнике мы видим что proxy заключены в таблицу, и у этой таблицы есть id 'theProxyList'

Посмотреть вложение 22960

Внутри таблицы находится тег tbody

Посмотреть вложение 22961

А внутри тега tbody есть теги tr при наведении на которые выделяется строка (линия) с нужными данными.

Посмотреть вложение 22962

Значит чтобы спарсить эту линию добавим в нашу функцию такую строку

Python:
line = soup.find('table', id='theProxyList').find('tbody').find_all('tr')
# Ищем с помощью find 'tbody' и с помощью find_all все 'tr'

Прекрасно, начало есть. Но это ещё не всё друзья, не так быстро дела делаются :)
В функцию get_page_data теперь добавим цикл, в котором мы будем обращаться по индексу к нужным данным. Дата и время проверки не будем парсить, так как это не такая нужная информация. Остальное преобразуем в текст с помощью text

Python:
for tr in line:
        td = tr.find_all('td')
        ip = td[1].text
        port = td[2].text
        country = td[3].text
        anonym = td[4].text
        types = td[5].text
        time = td[6].text

Теперь полученные данные запишем в словарь

Python:
       data = {'ip': ip,
                'Порт': port,
                'Страна': country,
                'Анонимность': anonym,
                'Тип': types,
                'Время отклика': time}

И выведем на печать print(data).

Осталось написать главную функцию, в ней мы принимаем url сайта, и по цепочке идёт обработка предыдущими функциями.


Python:
def main():
    url = 'http://foxtools.ru/Proxy'
    get_page_data(get_html(url))

Наконец-то запускаем скрипт и видим следующую картину:

Посмотреть вложение 22965

Данные успешно спарсились, но картинка не такая как хотелось бы. Присутствует куча мусора в виде \xa0, \r\n, \r\n\t\t\t\t\t
Значит будем от него избавляться. С помощью replace удалим всё лишнее, и для этого поправим наш цикл


Python:
    for tr in line:
        td = tr.find_all('td')
        ip = td[1].text
        port = td[2].text
        country = td[3].text.replace('\xa0', '')
        anonym = td[4].text.replace('\r\n        ', '')
        types = td[5].text.replace('\r\n\t\t\t\t\t', '').replace('\r\n        ', '')
        time = td[6].text

Запускаем по новой - другое дело, уже всё читабельно.

Посмотреть вложение 22966

Python:
import requests
from bs4 import BeautifulSoup


def get_html(site):
    r = requests.get(site)
    return r.text


def get_page_data(html):
    soup = BeautifulSoup(html, 'lxml')
    line = soup.find('table', id='theProxyList').find('tbody').find_all('tr')

    for tr in line:
        td = tr.find_all('td')
        ip = td[1].text
        port = td[2].text
        country = td[3].text.replace('\xa0', '')
        anonym = td[4].text.replace('\r\n        ', '')
        types = td[5].text.replace('\r\n\t\t\t\t\t', '').replace('\r\n        ', '')
        time = td[6].text

        data = {'ip': ip,
                'Порт': port,
                'Страна': country,
                'Анонимность': anonym,
                'Тип': types,
                'Время отклика': time}

        print(data)


def main():
    url = 'http://foxtools.ru/Proxy'
    get_page_data(get_html(url))


if __name__ == '__main__':
    main()


Ну вот мы и научились некоторым приёмам парсинга страниц. В следующей статье мы продолжим работать с этим парсером и добавим функционал.
До встречи! ;)
Было бы хорошо если бы TC объяснил


Для начала мы накидаем такую конструкцию

Python:
import requests
from bs4 import BeautifulSoup


if __name__ == '__main__':
main()

В чем и в какой программе ее накидывать и подробности а то ваще нечего не понятно зачем создавать тему для новичков не знаю A прыгать на C
 

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
В чем и в какой программе ее накидывать и подробности а то ваще нечего не понятно
В любом текстовом редакторе программы пишутся - например Notepad ++, SublimeText, Atom. Также есть куча сторонних интерпретаторов - Анаконда, Миниконда, Пэйчарм.

В конце статьи готовый исходный код - просто скопируйте и вставьте в Notepad ++, сохраните с расширение py - parser.py Всё ;)
 
  • Нравится
Реакции: Tihon49 и VPN
V

VPN

В любом текстовом редакторе программы пишутся - например Notepad ++, SublimeText, Atom. Также есть куча сторонних интерпретаторов - Анаконда, Миниконда, Пэйчарм.

В конце статьи готовый исходный код - просто скопируйте и вставьте в Notepad ++, сохраните с расширение py - parser.py Всё ;)
Можно ваш телеграмм?
 

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
Здравствуйте, объясните пожалуйста, где этот код запустить, что бы в итоге получить результат парсинга?
Опробовал на но пишет, что ошибка компиляции.
Думаю многие новички далекие от программирования не знают что с этим кодом делать...
В общем научите пожалуйста как из этого кода сделать программку)))
Спасибо.

В общем-то выше я ответил на этот вопрос
Подробнее:

1.) В системе должен быть установлен Python 3.
2.) Нужно установить все зависимости, иначе программа не запустится. Делайте через pip в терминале pip install имя пакета
3.) Скопировать код в любой редактор и сохранить с расширением py
4.) Запустить. Берите исходник со второй части статьи, там данные в текстовый файл записываются.

И ещё, чтобы не думали, что программа не работает - в директории с программой после запуска появится файл proxy.txt

P.S. Сложные программы в онлайн-интерпретаторах работать не будут. Всегда запускайте на своей машине.
 
Последнее редактирование:
  • Нравится
Реакции: alfi0
R

rtrjnc

Ясно, спасибо большое.
Понял. что мне нужно разобраться с 1 и 2 пунктом.
 

gerd

Green Team
21.09.2017
97
18
BIT
0
Привет всем.. Я только учусь всему. У кого не выходит 1. зависимости pip install не установит, пишем pip3 install bs4
2 после этого программа выдаст всякую охинею.....
python3 parser.py
Traceback (most recent call last):
File "parser.py", line 41, in <module>
main()
File "parser.py", line 37, in main
get_page_data(get_html(url))
File "parser.py", line 13, in get_page_data
soup = BeautifulSoup(html, 'lxml')
File "/usr/local/lib/python3.6/dist-packages/bs4/__init__.py", line 198, in __init__
% ",".join(features))
bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
суть вопроса можно прочитать здесь(

)

решение - пишем
pip3 install lxml
далее запускаем
python3 parser.py
итог все работает,автору спасибо.
 
  • Нравится
Реакции: Tihon49

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
после этого программа выдаст всякую охинею.....
Traceback (most recent call last):
............
bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?

Это не ахинея, а одна из самых лучших вещей.
Traceback - отслеживает ПРИЧИНУ ошибки. И вот если бы вы прочитали, что там написано, то не нужно было бы гуглить до посинения :)

А написано там следующее :
bs4.FeatureNotFound: не удалось найти строитель дерева с запрошенными функциями: lxml. Вам нужно установить библиотеку парсера.
Всё чётко и ясно )
 
  • Нравится
Реакции: Tihon49

DeDukTOR

Green Team
05.02.2020
31
3
BIT
0
Парни, у меня нескромный вопрос.
По мотивам этой и аналогичных статей я решил написать парсер проксей, но не могу составить одну строку.

Вот код:
Python:
import requests
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
url = "https://free-proxy-list.com/"
ua = UserAgent()
header = {
    'User-Agent': ua.random,
    'upgrade-insecure-requests': '1',
    'cookie': 'mos_id=CllGxlx+PS20pAxcIuDnAgA=; session-cookie=158b36ec3ea4f5484054ad1fd21407333c874ef0fa4f0c8e34387efd5464a1e9500e2277b0367d71a273e5b46fa0869a; NSC_WBS-QUBG-jo-nptsv-WT-443=ffffffff0951e23245525d5f4f58455e445a4a423660; rheftjdd=rheftjddVal; _ym_uid=1552395093355938562; _ym_d=1552395093; _ym_isad=2'
    }

page = requests.get(url, headers = header)
print(page.status_code)
print(page.text)

print("###" * 20)

soup = BeautifulSoup(page.text, "html.parser")
proxyes = soup.find('table').find('tbody').find('tr').find_all('td')
for name in proxyes:
    print(name.a['title'])

Вопрос:
Как должна выглядеть строка
proxyes = soup.find('table').find('tbody').find('tr').find_all('td')
Такая строка возвращает ошибку, но я несколько часов не могу сообразить, как спарсить прокси в формате : Ip:port.
Перебрал несколько комбинаций - не получается.
Где я ошибаюсь ?


P.S. Как ваши одобрения уже осточертели !!!
Это одобрения что-то решают на форуме ?
Или мои сообщения относятся к разряду особо опасных ?

Чего вы боитесь ?

Похоже на то, что пока кто-то прочитает это сообщение и пока кому-то придёт в голову хоть какое-то решение, то я и сам догадаюсь ))
 
Последнее редактирование:

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
Как должна выглядеть строка
proxyes = soup.find('table').find('tbody').find('tr').find_all('td')
Во-первых, в вашей строке нет класса таблицы, во-вторых на печать вы выводите совсем не то, что хотите вывести, нужно так:

Python:
for tr in proxyes:
        td = tr.find_all('td')
        ip = td[1].text
        port = td[2].text

        print(ip + ":" + port)

А если завернуть строку proxyes =.. в try except, то получите ответ This error was generated by Mod_Security
На сайте стоит WAF Mod_Security.

Вот, переписал код для сайта из статьи в формат, что вы хотите:

Python:
import requests
from bs4 import BeautifulSoup


def get_html(site):
    r = requests.get(site)
    return r.text


def get_page_data(html):
    soup = BeautifulSoup(html, 'lxml')
    line = soup.find('table', id='theProxyList').find('tbody').find_all('tr')

    for tr in line:
        td = tr.find_all('td')
        ip = td[1].text
        port = td[2].text

        print(ip + ":" + port)


def main():
    url = 'http://foxtools.ru/Proxy'
    get_page_data(get_html(url))


if __name__ == '__main__':
    main()

А вот как он выведет:


1111.png
 
  • Нравится
Реакции: DeDukTOR

DeDukTOR

Green Team
05.02.2020
31
3
BIT
0
РАБОТАЕТ )) Проверил ))

Ок, огромное спасибо за подсказку.
Вовремя, я вчера отложил решение этой задачи и до сих пор для меня это было не решённой проблемой ))
Вы не помогли ))


Но зачем функции ?
Я перечитал Вашу статью не менее пяти раз, пытался понять ход ваших мыслей. Сравнивал с аналогичными примерами других кодеров на другиг сайтах...
Вам не кажется, что код можно было написать без функций , используя только циклы ?
Я пытался написать без функций ))


P.S. Я не утверждаю, я только спрашиваю )
 

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
Вам не кажется, что код можно было написать без функций , используя только циклы ?

Конечно можно без функций. однако следует к ним привыкать - это правило хорошего тона. Допустим вы решите сделать большую программу, где будем много задач, и вот как раз функции можно применять многократно, в этом их задача и преимущество.

Кстати на этом сайте есть встроенный парсер, можно прямо спарсить с этого же сайта, если нужно, в 1 клик.

1111.png
 
  • Нравится
Реакции: Antony Hopkins и DeDukTOR

DeDukTOR

Green Team
05.02.2020
31
3
BIT
0
Кстати на этом сайте есть встроенный парсер, можно прямо спарсить с этого же сайта, если нужно, в 1 клик.
Да, я видел . Спасибо.
Но мне не нужен их парсер ))
Мне нужен собственный парсер )

Мне нужно спарсить прокси также с других сайтов, так что я ещё буду задавать аналогичные вопросы в этой теме.
Уверен, что при сборе проксей с других сайтов, код нужно будет править и у меня что-то пойдёт не так ))

Хм, какая-то нелепая описка с моей стороны :)
Не пойму, как я не заметил ошибку после написания сообщения.
Я хотел написать "Вы мне помогли".
Фраза должна была нести смысл благодарности, а получилось наоборот ))
 
29.07.2020
41
6
BIT
0
Вы тут можете что угодно утверждать, но представленный алгоритм парсинга прокси с указанного сайта является далеко не лучшим по следующим причинам:
  • в конкретном данном случае проще парсить прокси с помощью регулярных выражения с исходного кода страницы
  • алгоритм предполагает, что информацию о прокси предоставляет разработчик сайта, то есть информация не достоверна.
  • скорость прокси - относительна. Гораздо лучше написать скрипт проверки валидности награбленных прокси и проверять их(прокси) на доступность к тому или иному адресу, а заодно и скорость относительно своего местонахождения.
  • информацию о геолокации, ... и всю остальную нужную информацию проверять самостоятельно, а не полагаться на чужие результаты.

Кстати, какие имеются мнения:
каков способ поиска информации об IP является в Python наиболее оптимальным ?
 
Последнее редактирование:

Crypthas

New member
20.02.2020
1
0
BIT
0
Для тех, кто не понял.
Вот подробный разбор скрипта с пояснением к каждой строчке.

Python:
import requests, bs4 # импортируем модули
if __name__ == '__main__': [print({'ip': tr.find_all('td')[1].text, 'Port': tr.find_all('td')[2].text, 'Country': tr.find_all('td')[3].text.replace('\xa0', ''), 'Anonymity': tr.find_all('td')[4].text.replace('\r\n        ', ''), 'Type': tr.find_all('td')[5].text.replace('\r\n\t\t\t\t\t', '').replace('\r\n        ', ''), 'Ping': tr.find_all('td')[6].text}) for tr in bs4.BeautifulSoup(requests.get('http://foxtools.ru/Proxy').content, 'lxml').find('table', id='theProxyList').find('tbody').find_all('tr')] # парсим и выводим информацию об адресах
 

Proxy n1nja

Green Team
28.06.2018
118
149
BIT
0
Я вам немного функцию get_page_data переписал, что бы чуть почеловечнее выглядело и не надо много руками менять, если на сайте что-то поменяется.

Python:
def get_page_data(html):
    soup = BeautifulSoup(html, 'lxml')
    line = soup.find('table', id='theProxyList').find('tbody').find_all('tr')
    data = ("ip", "Порт", "Страна", "Анонимность", "Тип", "Время отклика")
    get_data = []

    for tr in line:

        td = tr.find_all('td')
        for i in td:
            step = i.text
            if step != '':
                get_data.append(i.text.strip().replace('\xa0', ''))
        result = {kay: value for (kay,value) in zip(data, get_data)}
        print(result)
 
  • Нравится
Реакции: Deniss Matjusevs

Cop999

New member
06.11.2020
2
0
BIT
0
Добрый вечер!

А что надо поменять в коде, что бы спарсить с этого сайта ?

У меня выдаёт ошибку

AttributeError: 'NoneType' object has no attribute 'find'
 

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
Добрый вечер!

А что надо поменять в коде, что бы спарсить с этого сайта ?

Всё надо менять. Парсеры пишутся индивидуально под каждый сайт, ведь у сайтов разные теги в исходном коде. В статье написано как смотреть теги в исходном коде. Кроме этого, на сайте который вы привели название колонок другие и т.д.

Если совсем коротко - вы не можете использовать один и тот же код просто заменив адрес сайта.
 

explorer

Platinum
05.08.2018
1 080
2 475
BIT
0
А что надо поменять в коде

Переписал парсер под этот сайт. Учите Python, 10 минут заняло. Работает в Windows и Linux.


Python:
import requests
from bs4 import BeautifulSoup


def get_html(site):
    r = requests.get(site)
    return r.text


def get_page_data(html):
    soup = BeautifulSoup(html, 'html.parser')
    line = soup.find('table', {'class': 'htable proxylist'}).find('tbody').find_all('tr')

    for tr in line:
        td = tr.find_all('td')
        proxy = td[0].text
        types = td[1].text
        country = td[2].text
        last_checked = td[3].text

        data = {'Proxy': proxy,
                'Type': types,
                'Country': country,
                'Last Checked': last_checked
                }

        print(str(data)[1:-1])


def main():
    url = 'https://www.ip-adress.com/proxy-list'
    get_page_data(get_html(url))


if __name__ == '__main__':
    main()
 
  • Нравится
Реакции: KDST и Cop999
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!