CoderCastrov logo
CoderCastrov
Парсер

Написание парсеров по-хорошему

Написание парсеров по-хорошему
просмотров
6 мин чтение
#Парсер

Если вы начинаете с from bs4 import BeautifulSoup, в 95% случаев вы делаете это неправильно.

burp community edition is enough to follow this tutorial

(не) важное предупреждение: всегда проверяйте политику веб-сайта, который вы пытаетесь парсить, это только для образовательных целей

Небольшое введение

это можно пропустить, как я всегда делаю, когда читаю книгу

Обычно, когда вы находите статью о парсинге в Python 3 (пожалуйста, перестаньте использовать Python 2.7.x), вы найдете что-то, что можно свести к следующему:

  • Как установить Python (если вы читаете учебник о том, как написать парсер на Python и у вас нет установленного Python, может быть лучше начать с чего-то другого)
  • Как установить BeautifulSoup4
  • Как спарсить веб-сайт с супер сложным HTML вроде <html>``<div class=’please_scrape_me’>hello world!</div>``</html>
  • Конец

В этой статье я хочу проанализировать реальный случай, где мы будем парсить данные о финансовых новостях с Yahoo, реализуя частное API, которое принимает на вход символ тикера и возвращает нам новости, без множества строк и сложных регулярных выражений для извлечения данных из HTML, а просто используя простые HTTPS-запросы.

Парсинг HTML против REST API

Я не считаю, что парсинг HTML имеет преимущества по сравнению с использованием REST API веб-сайта. Некоторые из преимуществ REST:

  • Данные структурированы и уже отформатированы в формате JSON или XML.
  • HTML на веб-сайтах может часто изменяться, в то время как API остаются неизменными.
  • Если ваше REST API было разработано для мобильного приложения, оно обычно не будет часто изменяться, потому что, если они сломают ваш парсер, они сломают свои старые сборки.

Burp Suite

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

Для анализа и работы с запросами HTTP/HTTPS/websocket Burp является одним из самых полезных и полных инструментов, которые вы можете использовать, и бесплатная версия Community Edition имеет почти все, что вам нужно. Я буду использовать только бесплатные функции.

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

Инструкции по настройке относятся к macOS, но вы легко можете найти эквивалентные инструкции для Windows/Linux. Если у вас уже есть рабочая настройка прокси-сервера Burp, просто перейдите к разделу "Сбор информации".

  1. Теперь нам нужно подключиться к локальному прокси-серверу Burp, вместо того, чтобы каждый раз изменять настройки прокси, давайте создадим новое местоположение сети macOS. Откройте System Preferences, Network, нажмите на выпадающее меню Location и выберите Edit Locations, нажмите на значок + и добавьте новое местоположение с именем Burp.
  1. После выбора нового местоположения перейдите в Advanced, Proxies, выберите Web Proxy (HTTP) и Secure Web Proxy (HTTPS) и введите localhost:8082 в поле адреса.

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

  1. Нам нужно настроить SSL-сертификат, после выбора местоположения Burp просто посетите http://burp в вашем браузере, и вы увидите экран, похожий на этот, нажмите на CA Certificate и установите его.

Если все работает правильно, каждый запрос будет перенаправлен в Burp, и вы сможете перенаправлять, отбрасывать, изменять каждый запрос. В Burp перейдите на вкладку Intercept и убедитесь, что Intercept включен, затем откройте https://google.com в вашем браузере, и вы увидите запрос со всеми параметрами в Burp.

Сбор информации

Первое, что нужно сделать, это просмотреть веб-сайт и проверить, какие запросы делаются и в каких из них возвращаются нужные нам данные. Перейдем в раздел финансы и посмотрим, какие запросы делаются, если мы ищем "Apple" в строке поиска, и открывая соответствующую страницу, перехватим и перенаправляем запрос по одному (или вы можете просто отключить перехват и перейти во вкладку История HTTP и искать там), вы заметите, что новости не загружаются, пока вы не перенаправите запрос на /quote/AAPL?p=AAPL&.tsrc=fin-src, поэтому, вероятно, этот запрос содержит нужные нам данные, давайте перейдем на вкладку История HTTP и проверим ответ.

если мы попытаемся найти новость, которую мы видим на веб-сайте, мы подтвердим, что новости находятся в ответе на этот GET-запрос /quote/

о, как плохо, они возвращают HTML!!1 нам нужно использовать парсинг HTML!!

Нет.

В настоящее время почти каждый веб-сайт имеет REST API, который предоставляет данные для фронтенда, но иногда, как в этом случае, я выбрал Yahoo, потому что он идеально подходит для учебника, они возвращают только HTML на фронтенд. Если раньше было редкостью найти веб-сайт без REST API, то почти невозможно найти приложение без REST API. Вот почему я написал в заголовке, что в 95% случаев не требуется парсинг HTML, но, очевидно, есть несколько случаев, когда веб-сайт возвращает только HTML, и нет мобильного приложения, и в таких случаях требуется парсинг HTML.

Время App Store

Сначала загрузите приложение из App Store или Play Store, затем настройте ваше устройство для работы с Burp Proxy.

iOS:

Настройка устройства iOS для работы с B...

Чтобы тестировать веб-приложения с использованием устройства iOS, вам необходимо настроить прослушиватель Burp Proxy для принятия соединений...

support.portswigger.net

Android:

Настройка устройства Android для работы с...

Чтобы тестировать веб-приложения с использованием устройства Android, вам необходимо настроить прослушиватель Burp Proxy для принятия соединений...

support.portswigger.net

Не забудьте перейти по адресу http://burp после настройки и установить CA-сертификат, иначе вы получите ошибки SSL при каждом запросе HTTPS.

Теперь давайте искать те же данные в приложении и посмотрим, какие запросы делаются.

Новости загружаются в приложение после выполнения этого GET-запроса /dp/v2/newsfeed. Изучив содержимое ответа, мы видим, что это json со всеми новостями, доступными на веб-сайте и в приложении!

На вкладке запроса нам нужно запомнить URL и User-Agent, который, как видите, является специфичным для приложения Yahoo.

Реализация на языке Python

Перед тем, как начать писать ваш скрипт, вы можете поиграть с параметрами, например, count может быть изменен на более высокое число, чем стандартное 10, и запрос будет работать без проблем, получая больше результатов за один вызов, меньше запросов, меньше вероятность блокировки.

Мы также видим, что mfin является необязательным, и если мы его удалим, ничего не изменится. Теперь, вместо использования множества find_all, find, xpath, css селекторов, вы можете просто сделать GET запрос с использованием модуля requests, вот так:

import requests

url = 'https://example.com/news'
params = {
    'count': 10,
    'mfin': 'example',
}

response = requests.get(url, params=params)
data = response.json()

print(data)

И вот! У нас есть все новости, которые мы видим на веб-сайте/приложении, уже структурированные в формате json, который мы легко можем разобрать и сохранить в базу данных или файл.

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

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

Выводы

Мы рассмотрели основы того, как найти API, которое возвращает нужные нам данные, и как реализовать его на Python. Используя API вместо парсинга HTML, у вас будет гораздо более стабильный парсер, который не требует обновления xpaths / class selectors каждую неделю. В следующей статье мы рассмотрим, как масштабировать такие парсеры с помощью асинхронной очереди задач, такой как Celery, и некоторых обходных путей в других сложных сценариях.

Если у вас есть вопросы, просто напишите его в комментарии или свяжитесь со мной в Instagram