CoderCastrov logo
CoderCastrov
Парсер

Мониторинг веб-страниц с помощью Python, Beautiful Soup и Twilio

Мониторинг веб-страниц с помощью Python, Beautiful Soup и Twilio
просмотров
7 мин чтение
#Парсер
Photo Credit: S & A

От компьютерных чипов до завтрака, глобальная пандемия COVID-19 вызвала проблемы на каждом этапе поставочной цепи. Ни одна другая отрасль не почувствовала этот кризис сильнее, чем велосипедная индустрия. В связи с COVID-19 веломагазины испытывают трудности в удовлетворении возросшего спроса из-за ненадежных запасов товаров. Покупка нового велосипеда или даже простой запчасти может занимать недели, а то и месяцы, и когда товары становятся доступными, они обычно быстро раскупаются. Некоторые продавцы предлагают возможность получать уведомления о поступлении товаров, но по моему опыту, эти уведомления обычно ненадежны. Другой вариант - нажимать кнопку обновления и надеяться на удачу.

Не было бы здорово автоматически получать оповещение в режиме реального времени (или близкого к реальному времени), если товар внезапно становится доступным?

Недавно я искал новый велосипед для своей жены, и выбор пал на велосипед Canyon (не спонсировано). Даже в нормальных условиях его можно приобрести с большим трудом, так как спрос, кажется, значительно превышает предложение. Не желая полагаться на их электронные уведомления, я решил создать скрипт на Python, который мониторит веб-страницу на наличие изменений и немедленно уведомляет меня по SMS и/или электронной почте. Конечно, если вы используете любой современный браузер, вы, вероятно, найдете расширение, которое делает именно это. Однако бесплатные версии часто имеют ограничения и, насколько мне известно, не включают функцию SMS.


Общая стратегия

Необходимые библиотеки

% python --version
Python 3.8.13

Реализация

1. Отправка запроса

Мы будем использовать модуль Requests для получения HTML-данных и парсить HTML с помощью модуля Beautiful Soup. Несколько замечаний, чтобы объяснить код ниже:

URL_TO_MONITOR | URL веб-страницы, которую мы хотим отслеживать. В данном случае это веб-страница с желаемым велосипедом Canyon, но это может быть любая веб-страница.

headers - это параметры, которые предоставляют серверу дополнительную информацию о запросе, такую как идентификатор приложения, операционную систему и т. д. Параметры ‘Pragma’: ‘no-cache’, ‘Cache-Control’: ‘no-cache’ добавляются для предотвращения кэширования, которое происходит, когда браузер или модуль запроса, в данном случае, сохраняют HTML с веб-страницы, чтобы ограничить HTTP-запросы. Чтобы убедиться, что у нас всегда есть самые актуальные данные, мы предотвращаем кэширование.

delay - это время ожидания между последовательными запросами. Важно установить подходящую задержку, так как частые последовательные запросы могут привести к тому, что сервер их интерпретирует как атаку отказа в обслуживании (DoS) и заблокирует IP-адрес. Здесь задержка установлена на 10 минут (900 секунд).

2. Парсинг HTML данных с помощью Beautiful Soup

Получив HTML данные, мы можем их распарсить с помощью модуля Beautiful Soup.

Beautiful Soup может использовать различные парсеры (html.parser, lxml, html5lib), и есть специальный раздел в документации по этой теме.

Различия между парсерами Beautiful Soup представляет одинаковый интерфейс для нескольких различных парсеров, но каждый парсер отличается. Разные парсеры создадут разные деревья разбора из одного и того же документа. Самые большие различия между парсерами HTML и парсерами XML.

У каждого парсера есть свои преимущества и недостатки, и выбор парсера зависит в основном от того, является ли HTML документ хорошо структурированным. В любом случае, парсер всегда должен быть явно указан, чтобы избежать неприятных сюрпризов. Для этой веб-страницы встроенный парсер Python (html.parser) работает отлично, но, конечно же, это может варьироваться.

2.1. Получение правильного HTML-элемента

Как получить правильный раздел веб-страницы для мониторинга? Одна из стратегий - хешировать содержимое всей веб-страницы и получать уведомления, если что-то изменяется. Однако размеры становятся доступными в разное время, и поскольку меня интересует только размер "small", получение уведомления, если появляются размеры "medium" или "large", не является идеальным. Поэтому нам нужно отслеживать изменения, применяемые к небольшому фрейму.

Мы можем получить доступ к исходному HTML-коду непосредственно в браузере с помощью инструментов разработчика, доступных во всех современных браузерах (я использую Chrome).

Сочетания клавиш для Mac: - Cmd + Shift + C для открытия инструментов разработчика в режиме "Инспектировать элемент" или переключения режима "Инспектировать элемент", если инструменты разработчика уже открыты. Сочетания клавиш для Windows/Linux: - Ctrl + Shift + C для открытия инструментов разработчика в режиме "Инспектировать элемент" или переключения режима "Инспектировать элемент", если инструменты разработчика уже открыты.

Изображение от автора

Ниже приведен код, который получает div для размера "small", а также сообщение о доступности. После некоторой очистки мы получаем текст: "Июль 2022", который будет служить нам базовым значением для сравнения.

print(availability_message)
>>>Июль 2022

3. SMS-уведомление при изменении веб-страницы

Теперь, когда у нас есть базовая доступность, мы можем установить условие для проверки, было ли обновление веб-сайта. Если это произошло, то мы получим текстовое сообщение, которое можно настроить с помощью Twilio API. Текстовое сообщение не только уведомляет нас о изменении доступности, но также содержит новую дату, если она доступна, или, надеюсь, сообщение о том, что товар в наличии.

3.1. Создание учетной записи Twilio

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

3.2. Храните свои токены вне Github!

Для доступа к Twilio вам понадобятся идентификатор учетной записи (account SID) и токен аутентификации (Auth token), но включение их в код может стать рецептом для беды, особенно если вы загружаете свой код на Github.

Почему частные исходные коды являются такой целью? То, что стало очевидным с изобилием успешных атак на исходный код, это то, что исходный код содержит много секретов (учетных данных), которые злоумышленники могут использовать для перемещения в различные системы. Эти секреты обычно защищены в высоко защищенных системах, однако, поскольку они настолько распространены в репозиториях кода, злоумышленники фактически идут по пути наименьшего сопротивления. Зачем пытаться получить доступ к зашифрованной и высоко защищенной системе, когда та же самая информация хранится в открытом виде в относительно незащищенной среде, такой как репозитории кода.Маккензи Джексон - разработчик-пропагандист в GitGuardian

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

  1. Убедитесь, что наш репозиторий имеет правильный .gitignore
  2. Создайте отдельный файл .env, чтобы хранить наши ключи API (и любые другие секреты)
  3. Считывайте переменные из этого файла как "переменные среды"
  4. Используйте переменные среды для заполнения нашего ключа API

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

Теперь мы можем использовать вышеуказанную функцию для настройки нашего SMS-сообщения оповещения:


Возвращаемся домой

Чтобы автоматизировать этот процесс, мы напишем новую функцию. Функция будет открывать веб-страницу, разбирать HTML, чтобы определить, была ли веб-страница обновлена, и отправлять сообщение, если это произошло. Функция также будет обновлять предыдущую дату доступности новыми датами, поэтому используется ключевое слово global. Это делается на случай, если доступность изменится на другую дату (обратите внимание, что изменение глобальных переменных в функции обычно считается плохой практикой программирования и не рекомендуется). Наконец, мы также добавляем журнал для отслеживания работы скрипта.

Затем мы можем объединить эту функцию с нашей функцией Twilio в главную функцию и создать бесконечный цикл для непрерывного мониторинга веб-страницы. Чтобы учесть возможные проблемы сети или другие проблемы, мы включаем блок try-except, и вот!

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

% python monitor_site.py

Прежде чем вы это поймете, вы получите оповещение о доступности товара!

Изображение от автора

Завершение

Вот и все! Надеюсь, вам понравился этот обзор. Есть несколько дополнительных шагов, которые мы не рассмотрели. Например, создание файла окружения и requirement.txt для управления пакетами Python. Это необходимо, чтобы воспользоваться переменными окружения для скрытия токенов API, что я настоятельно рекомендую. Существует несколько отличных руководств, независимо от того, используете ли вы PIP, Conda или Miniconda для управления пакетами и окружениями.

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

Полный код доступен на моей странице Github.

Спасибо!