Введение
Парсером принято называть приложение для сбора и систематизации информации с различных сайтов. В зависимости от поставленной задачи в качестве источника данных может выступать текстовое содержимое, HTML-код, элементы интерфейса и другие элементы. Процесс сбора данных называется парсингом.
Сегодня парсеры могут использоваться в разных сферах – интернет-маркетинг, наполнение партнерских магазинов, анализ конкурентов и для других задач. Во многих случаях подразумевается работа с большим массивом данных, вручную выполнить такую операцию достаточно сложно.
Термин произошел от английского выражения to parse, перевод – «по частям». Обобщенно процесс реализуется при помощи следующих этапов:
— сканирование исходного массива данных;
— выделение нужных элементов с учетом указанных параметров;
— сохранение информации в удобном для восприятия виде. Это может быть готовая база данных, таблица или текстовый документ с определенной структурой. Текстовый документ часто используется, если информацию необходимо загрузить в другую программу. В этом случае достаточно подготовить данные в нужной формате.
Использование парсеров предоставляет следующие преимущества:
— автоматизация процесса сбора и анализа данных, что позволяет снизить нагрузку на сотрудников;
— ускорение обработки больших массивов данных;
— возможность использовать встроенные фильтры для сбора информации, аккумулируя только нужный набор. Также можно сразу использовать инструменты для выявления ошибок. Использование готовых шаблонов позволяет быстро настроить нужный режим сканера.
В данной работе описывается процесс создания парсера для сбора информации с сайта Litres (популярный каталог книг). Реализована возможность сохранять картинки, настраивать глубину парсинга и нужные категории. Сохранение информации не используется – полученные данные сразу публикуются на указанном сайте непосредственно на текущей итерации цикла. Парсинг данных со страницы каталога осуществляется при помощи библиотеки BeautifulSoup4. Публикация обеспечивается при помощи библиотеки python-wordpress-xmlrpc (сайт на CMS WordPress). Пре этом предусмотрено сохранение исходной структуры – все книги попадают в нужную категорию. При необходимости можно изменить набор данных для переноса (дата публикации, автор, оценка и так далее). Информация сохраняется в отдельные переменные, что позволяет выбрать последовательность их размещения на конечной странице.
Использование данных инструментов позволило получить гибкое приложение, которое обеспечивает нужный функционал. В процесс сбора информации можно использовать большое количество параметров, включая тип публикации (текст или аудио), язык. Также есть возможность имитировать работу обычного браузера для исключения блокировки со стороны портала. В процессе настройки публикации обеспечивается возможность указать все необходимые параметры – автор, категория, дата публикации, возможность комментирования и другие.
Конечная цель – создание партнерского магазина с наполнением в автоматическом режиме. На каждой странице предусмотрена ссылка с реферальным кодом, которая ведет на исходную страницу. Возможность использовать готовое решение позволило решить сразу две задачи – отслеживание появление новинок для оперативной публикации в каталоге и загрузка большого количества книг. В процессе тестирования в течение суток было загружено порядка 5 тысяч новых книг, при этом введение ограничения было обусловлено возможностями используемого тарифа на хостинге (превышение лимита по нагрузке).
Поставленные задачи:
1. Изучить литературу и интернет-ресурсы, касающиеся выбранной темы.
2. Рассмотреть доступные инструменты для выбора оптимального варианта с учетом поставленной задачи.
3. Рассмотреть все основные требования к программам данного типа. Проанализировать возможные ограничения со стороны сайта и выбранного хостинга.
4. Составить алгоритм работы парсера и определить нужный набор данных для переноса.
5. Разработать приложение и протестировать его работу в реальных условиях. 6. Подготовить проект для развертывания на хостинге для работы в автоматическом режиме.
Анализ предметной области
Классический парсинг может использоваться в различных сферах, основной приоритет отдается коммерческому сектору. Это обусловлено тем, что такие инструменты позволяют при правильном подходе заметно повысить прибыль. Самый очевидный пример – сбор информации о потенциальных клиентах для последующих звонков. К примеру, это могут быть пользователи тематической группы в социальной сети. При этом уже на этапе сбора можно добавить дополнительные фильтры – пол, возраст, регион проживания и так далее.
В качестве распространенных схем можно выделить:
— поиск цен на определенные товары и услуги. Программа может обходить разные каталоги, формировать общую базу данных и сравнивать разные параметры. Например, можно найти самое выгодное предложение из полученного набора;
— поисковые фразы. Парсинг выдачи поисковых систем позволяет быстро собрать ключевые слова и текущие позиции сайтов. Такие массивы могут содержать тысячи поисковых фраз, вручную получить результат достаточно сложно.
— сбор целевой аудитории в социальных сетях. Такие ресурсы предоставляют возможность гибко настраивать режим поиска. Пользователи сами указывают в профиле нужные данные, например, город, интересы, группы. Более того, есть рекламные площадки, которые позволяют сразу в интерфейс загрузить полученную базу данных;
— поиск битых ссылок на сайте. Парсер может последовательно обойти все страницы и проверить корректность найденных ссылок. В этом случае формируется удобный отчет с указанием страниц;
— получение контента. Можно собирать статьи и публикации из различных источников. К примеру, можно создать собственный и магазин и быстро наполнить его из аналогичных ресурсов;
— работа со статистикой. Различные исследовательские центры используют для работы статистику, которая собирается в автоматическом режиме для дальнейшей обработки;
— анализ отзывов. Компании, которые занимаются отслеживанием репутации, должны оперативно отслеживать появление новых отзывов и сортировать их по оценке. Это позволяет предоставлять пользователям официальные ответы и поддерживать лояльность клиентов.
Анализ запросов на различных биржах показывает, что часто заказчики ищут исполнителей именно для создания собственных парсеров, данное направление достаточно востребовано уже не один год.
Основные требования и инструменты разработки
Требования к парсеру
К парсеру предъявляются следующие требования:
— список исходных категорий должен браться из текстового файла, расположен в том же каталоге. Это обусловлено тем, что редактироваться он будет достаточно редко;
— для сбора данных используется HTML-код загруженной страницы, обеспечивается загрузка изображения, категория сохраняется для восстановления структуры;
— в процессе парсинга должны передаваться указанные параметры браузера и cookie-файлы;
— сбор данных и публикация реализуется в одной итерации глобального цикла, данные предварительно не накапливаются;
— необходимо обеспечить постоянный обход по списку, при этом скорость можно ограничить, чтобы не создавать дополнительную нагрузку на второй сайт.
Для парсинга сайтов доступно большое количество готовых библиотек для Python: BeautifulSoup, Scrapy, Selenium, PySpider и другие. Они могут отличаться скоростью работы, возможностью обрабатывать динамичные страницы, доступным функционалом. Самим удобным считается BeautifulSoup, хотя он уступает по скорости работы и не всегда подходит для обработки ресурсов с динамическим контентом. Однако для поставленной задачи возможностей достаточно. Для формирования каталога динамический контент не используется, структура страницы относительно простая. Также на выбор повлияло наличие обширной документации и готовых примеров.
Для публикации на WordPress также можно использовать различные инструменты. Данный движок является одним из популярных, поэтому готовых решений много, включая собственные плагины для импорта из текстового файла или сбора данных с внешнего ресурса.
Базовый набор таких модулей позволяет публиковать записи и устанавливать основные параметры – дату, категорию, автора, возможность комментирования и так далее.
В данном проекте предусмотрен минимальный набор функций, поэтому можно использовать любую библиотеку. Работу облегчает то, что разработчики CMS уже предусмотрели функционал для работы через внешнее подключение – за это отвечает отдельный файл, к которому и подключается библиотека для дальнейшего взаимодействия. Такой подход значительно упрощает работу.
Для работы выбрана библиотека python-wordpress-xmlrpc. Решение обусловлено удобством работы – это одна из самых популярных библиотек, есть вся необходимая документация и большое количество примеров для работы.
Общий алгоритм работы скрипта:
— из текстового файла загружается список категорий для дальнейшей обработки, он сохраняется в отдельный список. Элементы списка обходятся в цикле;
— загружается страница текущей категории, активируются нужные параметры (язык, тип, рейтинг). В новый список загружаются все доступные ссылки на страницы книг;
— во вложенном цикле запускается обход книг (по ссылкам из полученного ранее списка);
— открывается страница текущей книги, в переменные сохраняется информация о книге – заголовок, описание, авторы, дата выхода, ISBN;
— подготовленный набор данных сразу публикуется на втором сайте;
— после обхода всех книг в списке, осуществляется переход к новой категории через новую итерацию внешнего цикла.
После запуска скрипт позволяет в автоматическом режиме наполнять каталог сайта. В рамках поставленной задачи для каждой категории каталога отслеживаются только две страницы – самые популярные предложения и новинки. Это позволяет упростить оптимизацию сайта, поскольку в каталоге присутствует много позиций, которые пользователи ищут очень редко. Немало книг опубликованы очень давно и морально устарели. Такие моменты необходимо учитывать в контексте оптимизации сайта. Поисковые системы плохо относятся к ресурсам, которые содержат большое количество невостребованного контента.
Настройка работы скрипта не требуется, все основные параметры указываются к коде. При необходимости, его можно доработать, чтобы он работал в постоянном режиме, осуществляя обход категорий в бесконечном цикле. После открытия очередной публикации извлекается идентификатор книги, далее осуществляется проверка на наличие в списке уже опубликованных ранее книг. Такая схема позволяет ускорить работу и сразу пропускать записи, которые уже были опубликованы ранее.
При обнаружении новых публикаций запускается процесс парсинга. Такой режим позволит оперативно отслеживать новинки и постоянно обновлять каталог. Это позволит улучшить поисковую оптимизацию – сервисы лучше индексируют сайты, которые постоянно обновляются. Также пользователи лучше относятся к сайту, который активно обновляется.
Дополнительные требования:
Во-первых, парсер должен быть устойчивым к изменениям в структуре HTML-страниц. Веб-сайты часто обновляют свой дизайн, и парсер должен быть способен адаптироваться к этим изменениям без необходимости полной переработки.
Во-вторых, необходимо соблюдать правила использования API и условия обслуживания сайтов. Некоторые ресурсы могут ограничивать количество запросов или запрещать парсинг. Поэтому важно изучить robots.txt сайта и следовать установленным правилам.
Третье требование – это скорость и эффективность. Парсер должен обрабатывать данные быстро, минимизируя время ожидания, чтобы не перегружать серверы целевых сайтов.
Кроме того, важно учитывать безопасность. Парсеры должны быть защищены от потенциальных угроз, таких как DDoS-атаки или блокировка IP-адресов.
Наконец, удобство использования и возможность масштабирования также являются важными аспектами. Хороший парсер должен иметь интуитивно понятный интерфейс и возможность работы с большими объемами данных без потери производительности.
Обход блокировок
Одна из основных проблем при создании парсеров – блокировка со стороны интернет-ресурса. Сканирование любого сайта неизбежно повышает нагрузку на инфраструктуру хостера, при определенных параметрах может даже снижаться скорость работы сайта. Более того, владельцы могут нести финансовые потери, поскольку вынуждены будут перейти на более дорогой тариф. Поэтому крупные сайты вынуждены принимать дополнительные меры для ограничения сторонней активности. Поскольку востребованный контент могут сканировать различные скрипты (включая поисковые системы), такая нагрузка может занимать основную часть всей активности.
Стоит отметить, что некоторые сервисы предоставляют готовые инструменты для быстрого доступа к данным, поскольку клиентам необходимо получать значительные объемы информации. Обычно это реализуется через интерфейс API с предоставлением всех необходимых функций. В виде отдельного раздела предоставляется подробное описание, могут быть добавлены готовые примеры. Такой подход позволяет оптимизировать нагрузку на сервер, поскольку внешние приложения сразу получают нужный контент.
Разработчикам необходимо знать основные механизмы, которые позволяют определять работу таких сканеров. По очевидным причинам достаточно сложно полноценно имитировать работу обычного пользователя, как минимум отличается скорость работы. Также часто используются одинаковые интервалы между запросами. Частично данную проблему можно решить за счет функции рандомизации и интеграции дополнительных пауз. Основная проблема в том, что парсеры обычно изначально создаются для загрузки больших массивов данных, что уже позволяет идентифицировать работу робота. Имитировать скорость перемещения между страницами реального пользователя бессмысленно, поскольку поставленную задачу не получиться выполнить за реальные сроки.
Также часто отследить активность можно по используемому IP-адресу. Со стороны сервиса достаточно просто сделать выборку в разрезе адреса, с которого поступили запросы. Такая выборка сразу покажет, в каких случаях использовался робот. Обычно при фильтрации проверка определяется по набору параметров, что позволяет идентифицировать устройство, даже если адрес периодически меняется. При фиксации нарушения информация заносится в черный список, что приводит к использованию определенных ограничений. К примеру, это может быть полная блокировка доступа или демонстрация дополнительной капчи для проверки.
Капча (Completely Automated Public Turing test to tell Computers and Humans Apart) – это тест, предназначенный для различения пользователей и автоматизированных систем. Существует несколько популярных типов капчи.
1. Текстовая капча. Пользователю предлагают ввести искаженные буквы и цифры. Этот метод часто используется, но его уязвимость к распознаванию с помощью ИИ делает его менее эффективным. Ранее это было достаточно популярное решение.
2. Графическая капча. Пользователям необходимо выбрать изображения, соответствующие заданной категории, например, «все изображения с автобусами». Это усложняет задачу для ботов, в данный момент одно из самых популярных решений. Обеспечивает высокую эффективность.
3. Капча от Google. Система использует поведенческий анализ, чтобы определить, является ли пользователь человеком. В некоторых случаях она предлагает простые задачи, такие как нажатие на кнопку «Я не робот». Использование большого количества факторов повышает общую эффективность инструмента.
4. Аудио капча. Предназначена для пользователей с ограниченными возможностями. Они слушают аудиозапись и вводят услышанные цифры или слова.
Каждый из этих типов капчи имеет свои преимущества и недостатки, и выбор зависит от специфики сайта и уровня необходимой защиты.
Для обхода таких блокировок используется подмена IP-адреса. Однако реализовать это становится все сложнее. Есть бесплатные прокси, но они часто имеют ограниченную скорость, есть вероятность, что адрес уже находится в черном списке. Обычно такие сервисы предлагают качественные аккаунты уже на платной основе.
Профессиональные решения для парсинга обычно содержат отдельный модуль для работы с прокси-серверами. Можно быстро импортировать их список из текстового файла, настроить режим смены. Отдельная опция позволяет проверять доступность очередного узла и при необходимости исключать его.
Следующий важный элемент – настройка заголовков и идентификатора пользовательского агента. Обозреватели хранят достаточно много информации, что позволяет однозначно определять основные параметры устройства и программной части. Крупные порталы часто отслеживают общую статистику и фиксируют активность, которая не соответствует указанным параметрам. Основные из них:
— проверка соответствия содержимого cookies и текущего аккаунта;
— формирование цифрового отпечатка на основе набора чужих и своих cookies;
— анализ набора шрифтов в системе;
— проверка соответствия локали, кодировки и так далее.
При создании парсеров есть возможность имитировать работу определенного браузера, а также предоставлять актуальные заголовки с основной технической информацией. Также можно реализовать набор готовых шаблонов, меняя их при необходимости. Это необходимо учесть еще на этапе проектирования и обеспечить заголовки:
— User-Agent;
— Accept;
— Accept-Encoding;
— Connection;
— Cache-Control;
— Accept-Language;
— Referer.
Пример заголовком можно посмотреть непосредственно в браузере, открыв нужный ресурс. Также для этого можно использовать специализированные ресурсы, которые позволяют сразу вывести нужную информацию в удобном виде.

Рисунок 1 – просмотр заголовков в браузере
Также модуль безопасности сайта может отслеживать поведение пользователя. Например, переход сразу на страницу с нужными фильтрами, использование прямых ссылок вместо последовательного перемещения по структуре.
Сайты используют различные методы для определения, является ли пользователь человеком или роботом. Одним из основных признаков является поведение пользователя на странице. Роботы часто проявляют аномалии в активности: они могут заполнять формы слишком быстро, переходить по ссылкам с высокой скоростью или совершать действия в нехарактерные для человека временные промежутки.
Также важным фактором является стиль использования мышки. Люди обычно перемещают курсор плавно, с паузами, в то время как боты могут делать это резко и без логики. Кроме того, сайты анализируют паттерны кликов: например, люди чаще делают паузы между кликами и взаимодействуют с элементами страницы более разнообразно.
Другим признаком может быть IP-адрес. Если множество запросов поступает с одного IP, это может указывать на использование бота. Наконец, системы могут проверять наличие JavaScript и куки – многие боты не поддерживают эти технологии. Все эти методы помогают сайтам эффективно различать людей и автоматизированные системы.
Некоторые сайты активно используют JavaScript для вывода основного контента на страницы сайта. Если просто посмотреть HTML-код такой страницы, но вместо текста там будет набор JS-скриптов. Также часть контента можно подгружаться уже в процессе работы со страницей, например при прокрутке. Такие решения часто можно встретить на различных информационных сайтов – публикации появляются по мере прокрутки страницы бесконечно.
Это осложняет парсинг, поскольку нет возможности напрямую извлечь нужные данные. Для решения данной проблемы часто используются специальные браузеры без интерфейса. Это позволяет сформировать итоговую страницу и только после этого запустить сканирование данных. Обычно это решается в виде отдельной библиотеки, которая обеспечивает нужный функционал. Для Python самой популярной считается библиотека Selenium.
Чтобы учесть все особенности конкретного сайта необходимо детально проанализировать все особенности вывода контента. Практика показывает, что часто можно найти обходные пути для извлечения контента.
Следующий важный нюанс – правильное отображение cookies. Нередко сайты могут заблокировать доступ, даже если с одного устройства будут входы в разные аккаунты, даже если это делают разные пользователи. В процессе разработки парсера необходимо извлечь реальный куки-файл и обеспечить вывод содержимого в процессе работы кода.
Cookies – это небольшие текстовые файлы, которые веб-сайты сохраняют на устройствах пользователей при открытии сайта. Они содержат информацию, которая помогает улучшить пользовательский опыт и обеспечивать функциональность сайтов. Например, можно упростить авторизацию, отображать подходящий контент, запоминать историю страниц и так далее. Основные типы информации, хранящейся в cookies, включают:
1. Идентификация пользователя. Cookies могут хранить уникальные идентификаторы, позволяющие сайту распознавать пользователя при повторных посещениях.
2. Настройки и предпочтения. Они сохраняют настройки, такие как язык интерфейса или темы оформления, что позволяет повысить удобство использования сайта.
3. Содержимое корзины покупок. В интернет-магазинах cookies помогают отслеживать товары, добавленные в корзину, даже если пользователь покинул сайт. Также можно сформировать блок похожих предложений для повышения конверсии.
4. Аналитика и реклама. Cookies используются для сбора данных о поведении пользователей на сайте, что помогает в таргетированной рекламе.
В качестве дополнительного инструмента ресурсы могут использовать специальные страницы ловушки. Схема достаточно простая – создается отдельная страница, на которую пользователь не может попасть через интерфейс сайта. Например, ссылка отображается в коде, но скрыта визуально. В этом случае открытие такой страницы позволяет однозначно определить, что доступ осуществляет не человек. Реализовать это также довольно просто – можно добавить к ссылке атрибут «display: none».
С одной стороны, можно в коде предусмотреть обход таких ловушек. Например, отслеживая такие атрибуты CSS, проверяя используемый цвет, вынос за пределы зоны видимости и так далее. С другой стороны, таких методов много, можно придумать уникальную схему. Отследить все возможные комбинации очень сложно.
Если система безопасности фиксирует отклонения от стандартной модели поведения, обычно в качестве первого этапа используется вывод требования подтвердить, что доступ осуществляется не роботом. Обычно для этого используются различные капчи – выбрать нужную картинку, ввести последовательность, переместить элемент и так далее. Для обхода можно использовать сторонние сервисы для автоматического, однако они не всегда эффективны. Самый надежный вариант – использование специализированных бирж, которые привлекают для решения реальных пользователей, однако большие объемы могут стоить очень дорого.
Еще один эффективный механизм блокировки парсинга – принудительное ограничение на количество запросов в секунду с одного адреса. Для рядового пользователя это не влияет на работу с сайтом, поскольку скорость перехода между страницами низкий. Действующие лимиты могут быть обозначены в формате заголовка X-RateLimit-Limit (количество запросов в секунду). При превышении данного параметра может вызываться капча, возвращаться ошибка 429 (много запросов) или 503 (сервер недоступен). Для обхода данного ограничения со стороны парсера можно добавить длительную паузу или сменить цифровой отпечаток.
Практика показывает, что при необходимости сайты могут реализовать надежную защиту от сканирования, использую нужную комбинацию различных инструментов. Однако и развитие программ для сканирования также позволяет обходить такие блокировки. В самом сложном случае можно просто использовать реальный браузер и полностью имитировать поведение пользователя, используя рандомные паузы нужной длительности. Однако для больших объемов данных потребуется очень много времени.
В процессе работы в данной сфере также необходимо всегда учитывать юридические особенности парсинга сторонних сайтов.
Многие сайты имеют свои условия использования, которые могут запрещать парсинг. Например, в разделе «robots.txt» можно указать, какие части сайта разрешено индексировать поисковым системам и парсерам. Нарушение этих условий может привести к юридическим последствиям, включая блокировку доступа к сайту или судебные иски.
Законность парсинга может зависеть от типа данных, которые извлекаются. Если данные являются общедоступными и не нарушают авторские права или права на конфиденциальность, то в большинстве случаев парсинг будет законным. Если информация защищена авторскими правами или содержит личные данные, то ее сбор может быть незаконным.
Кроме того, в некоторых странах существуют законы о защите данных, такие как GDPR в Европе, которые регулируют обработку персональной информации. Парсеры, собирающие такие данные, должны соблюдать эти законы.
Язык программирования
Для проекта используется язык программирования Python c набором нужных библиотек.
Python – это высокоуровневый язык программирования, который был создан в конце 1980-х годов Гвидо ван Россумом и впервые выпущен в 1991 году. С тех пор он стал одним из самых популярных языков в мире, благодаря своей простоте, читаемости и широкому спектру применения.
Одной из ключевых особенностей Python является его синтаксис, который стремится быть максимально понятным и лаконичным. Это позволяет разработчикам быстро осваивать язык и писать код с минимальным количеством строк. Python поддерживает множество парадигм программирования, включая объектно-ориентированное, функциональное и процедурное.
Возможности Python:
— веб-разработка. Python активно используется для создания веб-приложений. Популярные фреймворки, такие как Django и Flask, позволяют быстро разрабатывать сложные веб-сайты и API. Django предлагает мощные инструменты для работы с базами данных и аутентификацией пользователей, а Flask обеспечивает гибкость и минимализм;
— научные вычисления и анализ данных. Python стал стандартом в области анализа данных благодаря библиотекам, таким как NumPy, Pandas и SciPy. Эти инструменты позволяют эффективно обрабатывать и анализировать большие объемы данных. Библиотека Matplotlib используется для визуализации данных, а Seaborn делает графики более информативными и красивыми;
— машинное обучение и искусственный интеллект: С помощью библиотек TensorFlow, Keras и Scikit-learn Python стал основным языком для разработки моделей машинного обучения. Эти инструменты позволяют создавать нейронные сети и применять алгоритмы обучения на больших наборах данных;
— автоматизация и скрипты. Python идеально подходит для написания скриптов, которые автоматизируют рутинные задачи. Это может включать обработку файлов, взаимодействие с API и сбор данных с веб-сайтов (веб-скрейпинг) с помощью библиотеки Beautiful Soup;
— разработка игр. Хотя Python не так широко используется в игровой индустрии, как C++ или C#, он имеет библиотеки, такие как Pygame, которые позволяют создавать простые игры и обучающие приложения;
— интернет вещей (IoT): Python также нашел применение в разработке приложений для IoT. Библиотеки, такие как MicroPython и CircuitPython, позволяют программировать микроконтроллеры и устройства с ограниченными ресурсами.
Выбор библиотек для работы
Основное требование для парсера в рамках текущего – простое извлечение данных из статичных страниц.
BeautifulSoup. Одна из самых популярных библиотек, позволяет быстро преобразовать сложные XML и HTML документы в удобный набор данных. После конвертации все элементы представляют собой дерево тегов, что позволяет быстро формировать вложенные запросы для доступа к нужному объекту.
Это позволяет при помощи указания нужных параметров быстро извлечь нужные данные. Основной упор сделан на простоту работы, поэтому освоить парсинг могут и пользователи без опыта.
Основные возможности BeautifulSoup включают:
1. Парсинг HTML и XML. Поддерживает различные парсеры, такие как lxml и html.parser, что позволяет обрабатывать даже некорректно сформированные документы. Разработчик получает возможность сформировать набор инструментов под определенные задачи.
2. Поиск элементов. Библиотека предлагает методы для поиска элементов по тегам, атрибутам и тексту, что делает извлечение нужной информации быстрым и удобным. Даже в сложных структурах можно быстро сформировать вложенные запросы, чтобы пройти в нужные контейнеры и добраться до элемента.
3. Изменение структуры документа. Пользователи могут легко добавлять, изменять или удалять элементы, что позволяет динамически редактировать содержимое. Это дополнительно расширяет возможности библиотеки.
4. Поддержка кодировок. BeautifulSoup автоматически обрабатывает различные кодировки, облегчая работу с многоязычными страницами.
С помощью BeautifulSoup разработчики могут эффективно собирать и анализировать данные из интернета, что открывает широкие возможности для создания различных приложений.
Lxml. Еще ода популярная библиотека, которая отличается высокой скоростью работы и большим набором функций. Сфера использования – сложный парсинг, в котором требуется высокая скорость работы. Для расширения возможностей предусмотрена поддержка языка запросов XPath, который обеспечивает навигацию по атрибутам и элементам страницы.
Scrapy. Мощный фреймворк с набором инструментов для веб-скрапинга. Позволяет автоматизировать сбор информации с сайтов со сложной структурой. Хорошо подходит для работы с большими массивами данных. Работа осуществляется при помощи встроенных пауков, которые следуют набору инструкций. Поддерживаются асинхронные запросы, что позволяет дополнительно оптимизировать работу.
Selenium. Инструмент для автоматизации работы обозревателей. Основная сфера использования – тестирование веб-приложений. Это позволяет использовать библиотеку для сбора информации со страниц с динамическим контентом.
В процессе работы можно запустить внешний браузер и управлять им при помощи команд. Это открывает широкие возможности – можно заполнять формы, взаимодействовать с кнопками для получения нужной информации.
PyQuery. Библиотека для парсинга HTML, которая позволяет использовать jQuery-подобный синтаксис. Ее часто предпочитают программисты, которые знакомы с jQuery, это заметно облегчает работу.
Для поиска и взаимодействия с элементами страницы используются CSS-селекторы, что упрощает формирование нужного запросы и обеспечивают высокую гибкость.
Основные возможности Selenium включают:
1. Автоматизация браузеров. Selenium поддерживает работу с различными браузерами, такими как Chrome, Firefox, Safari и Edge, позволяя запускать тесты в разных средах. Это актуально, поскольку разные приложение могут иметь отличия в обработке данных.
2. Запись и воспроизведение действий. Библиотека позволяет записывать действия пользователя и воспроизводить их, что упрощает процесс тестирования. Такие наборы можно сохранять для дальнейшего использования.
3. Управление элементами страницы. Selenium предоставляет методы для взаимодействия с элементами на странице – клики, ввод текста, выбор из выпадающих списков и т.д.
4. Обработка динамического контента. С помощью Selenium можно работать с JavaScript-приложениями, так как библиотека позволяет ожидать загрузки элементов и взаимодействовать с динамически изменяемым содержимым.
5. Поддержка различных языков программирования. Хотя основным языком является Python, Selenium также поддерживает Java, C#, Ruby и другие языки.
Requests-HTML. Библиотека позволят кроме парсинга осуществлять рендеринг веб-страниц. Есть возможность полноценно обрабатывать динамические страницы без использования сторонних библиотек. Поддерживается рендеринг JavaScript, что позволяет обрабатывать динамический контент.
Веб-интерфейс
В процессе работы над проектом также возникла необходимость разработать простой веб-интерфейс для управления парсером после публикации на сервере. Выбор производился между Django и Flask, поскольку они изучались в рамках курса, что позволит закрепить полученные навыки.
Основное различие между Flask и Django – во втором случае предоставляется полнофункциональная среда формата Model-View-Controller, что позволяет создавать сложные проекты.
Django – это высокоуровневый веб-фреймворк на языке Python, который упрощает разработку сложных веб-приложений. Он был создан с акцентом на быструю разработку и чистый, прагматичный дизайн. Одной из ключевых особенностей Django является подход «всё включено», который предоставляет разработчикам множество встроенных инструментов и библиотек.
Основные возможности Django включают ORM (Object-Relational Mapping) для работы с базами данных, систему маршрутизации URL, поддержку аутентификации пользователей, админ-панель для управления контентом и механизмы для работы с формами и валидацией данных. Также фреймворк обеспечивает безопасность приложений, защищая от распространённых уязвимостей, таких как SQL-инъекции и XSS.
Django широко используется в различных сферах, включая создание корпоративных сайтов, социальных сетей, систем управления контентом и веб-приложений для электронной коммерции. Благодаря своей гибкости и масштабируемости, он подходит как для стартапов, так и для крупных компаний, желающих быстро развивать свои проекты.
Flask – это легковесный веб-фреймворк на языке Python, который идеально подходит для создания простых и масштабируемых веб-приложений. Он был разработан с акцентом на простоту и гибкость, что делает его отличным выбором как для новичков, так и для опытных разработчиков. Flask следует архитектурному стилю MVC (Model-View-Controller), что позволяет организовать код в структурированном виде.
Одной из ключевых особенностей Flask является его модульность. Он предоставляет базовый набор инструментов для работы с HTTP-запросами, маршрутизацией URL и шаблонами, но при этом позволяет легко интегрировать сторонние библиотеки и расширения для добавления функциональности. Это делает Flask особенно привлекательным для создания RESTful API и микросервисов.
Flask широко используется в различных сферах, включая разработку веб-приложений, прототипирование, создание API для мобильных приложений и интеграцию с различными сервисами. Благодаря своей простоте и гибкости, Flask стал популярным выбором для стартапов, исследовательских проектов и образовательных целей.
Это позволило платформе занять собственную нишу – она хорошо подходит для небольших проектов. Это могут быть небольшие блоги, одностраничные приложения и так далее. Практика показывает, что для создания таких ресурсов функционал Django избыточен. Для текущей задачи был выбран Flask, его возможностей вполне достаточно. Более того, остается возможность для дальнейшего расширения проекта.
Выбор площадки для публикации парсера
Хостинг представляет собой площадку, на которой публикуется и функционирует сайт, приложение или игровой сервер. Если сильно упростить, то хотинг представляет собой ПК, который постоянно работает и подключен к внешней сети. Технически, можно использовать любой компьютер в обычной квартире, обеспечив бесперебойную работу. После настройки программной части уже можно использовать устройство для размещения простых чат-ботов или даже сайтов пропускной способности интернет-канала достаточно. Такое решение не является популярным, поскольку сложно обеспечить бесперебойную работу.
Для серьезных проектов уже используют профессиональные хостинги, которые обеспечивают необходимую инфраструктуру и панель управления. Для этого предусмотрен собственный штат специалистов, служба поддержки и так далее. Однако такие сервисы преимущественно заточены под веб-сайты. Для запуска скриптов на разных языках программирования уже могут потребоваться дополнительные модули.
Хостинг – это услуга, предоставляющая пользователям возможность размещать свои веб-сайты и приложения на серверах, доступных в интернете. Суть хостинга заключается в том, что провайдер выделяет ресурсы (диск, оперативную память, процессорное время) для хранения файлов сайта и обеспечения его доступности для пользователей.
Существует несколько типов хостинга. Виртуальный хостинг позволяет многим сайтам использовать один сервер, что делает его экономически выгодным для небольших проектов. Выделенный сервер предоставляет полный контроль над ресурсами, что подходит для крупных сайтов с высоким трафиком. Облачный хостинг обеспечивает гибкость и масштабируемость, позволяя увеличивать или уменьшать ресурсы в зависимости от потребностей.
Кроме того, хостинг может включать дополнительные услуги, такие как регистрация доменов, поддержка баз данных, системы управления контентом и инструменты для резервного копирования.
Размещение Python-скриптов в сети для их запуска и постоянной работы может осуществляться несколькими способами, в зависимости от требований проекта, бюджета и необходимых ресурсов. Основные из них:
Виртуальные серверы (VPS). Это один из самых популярных способов размещения Python-приложений. VPS предоставляет пользователю выделенные ресурсы на сервере, что позволяет настроить окружение под свои нужды. Можно установить необходимые библиотеки и фреймворки, такие как Flask или Django, и запускать скрипты в фоновом режиме.
Облачные платформы. Сервисы, такие как AWS, Google Cloud или Azure, предлагают мощные инструменты для развертывания и управления Python-приложениями. Можно использовать контейнеризацию с Docker или платформы как услугу (PaaS), такие как Heroku, которые упрощают процесс развертывания приложений.
Функции как услуга (FaaS). Платформы, такие как AWS Lambda или Google Cloud Functions, позволяют запускать Python-код в ответ на события без необходимости управлять серверами. Это идеальный вариант для выполнения задач по триггеру, таких как обработка данных или выполнение периодических задач.
Платформы для хостинга веб-приложений. Сервисы вроде Heroku и PythonAnywhere предлагают простые способы развертывания Python-приложений с минимальными настройками. Эти платформы позволяют быстро развернуть приложение, предоставляя удобные инструменты для управления зависимостями и окружением.
Контейнеризация. Использование Docker для упаковки вашего приложения в контейнер позволяет легко переносить его между различными средами. Вы можете развернуть контейнер на любом сервере или в облаке, что обеспечивает гибкость и масштабируемость.
Каждый из этих способов имеет свои преимущества и недостатки, поэтому выбор зависит от конкретных требований вашего проекта, бюджета и ожидаемой нагрузки.
Для простых скриптов вполне можно использовать бесплатные сервисы. К самым популярным можно отнести Heroku и Pythonanywhere. Возможностей у таких платформ достаточно много:
— большое количество библиотек, есть возможность устанавливать дополнительные через easy_install и pip;
— полноценная панель управления;
— поддерживаются все популярные WSGI веб-фреймворки;
— поддержка баз данных;
— интеграция с внешними сервисами;
— модуль настройки заданий (аналог cron).
Стоит учитывать, что в бесплатной версии предусмотрены определенные ограничения, для доступа используется домен второго уровня. Платформа больше ориентирована на обучение, для серьезных проектов она подходит плохо.
Интернет-хостинг при определенных условиях также можно использовать для запуска скриптов. После изучения инструкции можно развернуть отдельный контейнер и установить необходимые компоненты.
Ключевые особенности:
— необходимо больше контроля над выбранным сервером;
— используемое оборудование должно обеспечивать нужную производительность;
— набор доступных программных инструментов должен полностью соответствовать поставленным задачам.
Для работы Python-приложений часто требуется запуск длительных процессов. Провайдеры к такой активности обычно относятся негативно, нередко принудительно завершая такие процессы для экономии аппаратных ресурсов.
Виртуальный хостинг не подходит для размещения Python-приложений. Необходимо сразу рассматривать более реальные варианты, чтобы оборудование могло корректно запустить все необходимые компоненты.
Наиболее подходящий вариант – выделенный сервер. Как видно из названия, в этом случае используется отдельный компьютер в дата-центре. Это позволяет получить полный контроль – установить нужную операционную систему и набор программ. Также появляется возможность тонко настраивать систему под текущие потребности.
Если бюджет ограничен, можно рассмотреть виртуальные сервера (VPS/VDS). Возможности практически аналогичны, при этом есть возможность выбрать подходящий тариф с учетом текущих потребностей. В этом случае программными методами обеспечивается изоляция отдельных серверов, что не позволяет одному аккаунту нарушить работу другого.
После выбора хостера, рекомендуется сразу связаться со службой поддержки, чтобы уточнить все особенности предоставления услуг с учетом текущих потребностей. Важно проверить версию Python, наличие поддержки подключения по SSH, особенности работы с базами данных и так далее.
С учетом всех особенностей проекта было принято решение использовать для деплоя хостинг Beget. Выбор обусловлен тем, что на нем уже расположен сайт, который будет наполняться контентом при помощи парсера. Текущий тариф обеспечивает необходимую производительность. Под задачу создан отдельный поддомен, на котором развернут контейнер с нужными скриптами.
Выбор среды разработки
Список популярных сред разработки для Python:
PyCharm. Мощная IDE от JetBrains, предлагающая интеллектуальную поддержку кода, инструменты для отладки и интеграцию с системами контроля версий. Подходит как для новичков, так и для профессионалов.
Visual Studio Code. Легкий редактор от Microsoft с поддержкой множества расширений для Python. Обладает функциями автозавершения, отладки и интеграции с Git.
Jupyter Notebook. Интерактивная среда, идеально подходящая для анализа данных и машинного обучения. Позволяет запускать код по ячейкам и визуализировать результаты в реальном времени.
Spyder. IDE, ориентированная на научные вычисления и анализ данных. Включает встроенный редактор, консоль и инструменты для работы с библиотеками, такими как NumPy и Pandas.
Atom. Текстовый редактор от GitHub, который можно настроить под Python с помощью плагинов. Поддерживает совместную работу и предлагает удобный интерфейс.
Эти среды предлагают различные функции и возможности, что позволяет разработчикам выбирать наиболее подходящие инструменты для своих задач. Для текущего проекта была выбрана платформа Visual Studio Code.
Visual Studio Code (VS Code) – это мощная и популярная среда разработки, созданная компанией Microsoft, которая завоевала признание среди разработчиков благодаря своей универсальности и множеству функций.
Одной из ключевых особенностей VS Code является его легкость и высокая производительность. В отличие от более тяжелых интегрированных сред разработки, VS Code запускается быстро и не требует значительных ресурсов системы, что позволяет работать на различных устройствах, включая менее мощные ноутбуки.
Интуитивно понятный интерфейс делает его доступным как для новичков, так и для опытных программистов. Пользователи могут легко настраивать рабочее пространство под свои нужды, изменяя темы оформления, шрифты и расположение панелей. Кроме того, VS Code поддерживает множество языков программирования, включая JavaScript, Python, C++, Java и многие другие, что делает его универсальным инструментом для разработки.
Одним из значительных преимуществ VS Code является обширная библиотека расширений. В Marketplace доступны тысячи плагинов, которые добавляют функциональность, такую как поддержка новых языков, инструменты для отладки, интеграция с системами контроля версий и многое другое. Это позволяет разработчикам адаптировать среду под свои конкретные задачи.
Интеграция с Git и другими системами контроля версий также является важной особенностью. VS Code позволяет удобно управлять версиями кода прямо из редактора, что упрощает процесс разработки и совместной работы в команде.
Поддержка IntelliSense – еще один сильный аргумент в пользу VS Code. Эта функция предлагает автозавершение кода, подсказки по синтаксису и документации, что значительно ускоряет процесс написания программного обеспечения и снижает количество ошибок.
Наконец, активное сообщество пользователей и разработчиков обеспечивает постоянное обновление и улучшение среды. Регулярные обновления добавляют новые функции и исправления, а пользователи могут делиться своими наработками и получать помощь через форумы и сообщества.
В целом, Visual Studio Code сочетает в себе легкость, мощные функции и гибкость, что делает его отличным выбором для разработчиков всех уровней.
Разработка парсера
Основной функционал
Уже на этапе тестирования необходимо обеспечить защиту от блокировки со стороны сайта. Простая проверка показала, что обход каталога быстро приводит к появлению капчи, что приводит к остановке процесса. Если вручную подтвердить запрос, сканирование продолжится, но достаточно быстро возникнет новый. Если игнорировать такие ситуации, что ресурс может добавить текущее соединение в черный список
Дальнейшая проверка показала, что для обхода достаточно заполнить и добавить к запросам два параметра – cookies и headers. Извлечь нужные данные можно через панель разработчика в браузере. Далее они передаются в нужные переменные и добавляются к запросам на сайт.

Рисунок 2 – пример заполнения headers
Пример кода для отправки запросов на загрузку очередной категории представлен ниже. Категории берутся из подготовленного списка в цикле.

Рисунок 3 – запрос на загрузку категории
Поскольку высокая скорость работы не требуется, данных методов уже достаточно для обхода блокировки со стороны сайта. В процессе тестирования максимальная скорость устанавливалась в пределах 300 страниц в час, ограничения со стороны каталога не фиксировались. В реальной работе готового парсера скорость устанавливается порядка 100 страниц в час, для этого используется набор пауз между запросами.
Скрипт сбора данных
За сбор данных с выбранной страницы отвечает библиотека BeautifulSoup. Также используются два списка, загружаемых с внешнего текстового файла. В первом хранится список категорий для обхода. Это позволяет при необходимости адаптировать работу скрипта под определенные задачи, например, указать нужные категории или метод сортировки – путем отдельных параметров в URL можно отслеживать только новые поступления или популярные книги.

Рисунок 4 – Исходный список подкатегорий для обхода
Второй текстовый файл хранит список идентификаторы уже опубликованных книг. При запуске скрипта он загружается в отдельную переменную. При открытии очередной книги извлекается ее идентификатор, далее проверяется его наличие в списке. Если элемент уже присутствует, инициируется переход к очередной итерации. В противном случае производится извлечение нужного набора данных для переноса. Если все этапы пройдены успешно, текущий идентификатор добавляется в список и далее сохраняется в файл.

Рисунок 5 – Извлечение списков из текстовых файлов
Открытая страница сохраняется в переменную в виде структуры элементов, что позволяет использовать наборы фильтров для поиска. Все необходимые элементы сохраняются в переменные.
Анализ особенностей работы каталога показал, что установка нужных фильтров реализуется путем добавления нужных параметров к текущему URL. Это позволяет заранее сохранить их в виде списка и добавлять по мере необходимости.

Рисунок 6 – Работа фильтров
Для поиска нужного селектора удобно использовать собственные инструменты браузера. Можно сразу просмотреть структуру текущей страницы и выбрать нужный элемент для доступа.

Рисунок 7 – Просмотр структуры документа (автор книги)
Далее в коде выбранный элемент указывается при поиске. При необходимости можно использовать вложенные запросы – получить доступ к нужному контейнеру и уже в нем запустить новый поиск. Важно проверить, что выбран уникальный набор селекторов, который позволяет однозначно идентифицировать нужный элемент. При реализации в коде при необходимости сразу добавляется проверка на существование такого элемента на странице. Это позволяет сразу обрабатывать различные ситуации. В данном случае для книг не всегда указывается автор, поэтому иногда блок нужно пропустить. Реализуется это достаточно просто – перед запуском новой итерации нужные переменные очищаются. Далее перед публикацией проводится новая проверка, если переменная осталась пустой – блок пропускается.

Рисунок 8 – Поиск авторов на странице
В процессе создания парсера подготавливается список элементов, которые необходимо извлечь. Далее для каждого выбирается набор селекторов для поиска. По аналогичному принципу работает множественный поиск, например, когда нужно собрать со страницы категории все ссылки на книги.

Рисунок 9 – Извлечение данных
Далее основные данные добавляются в новую переменную для формирования текста публикации. После подготовки осуществляется публикация записи при помощи библиотеки python-wordpress-xmlrpc. В переменную wpcontent в нужной последовательности вносятся собранные данные, при необходимости добавляются нужные HTML-теги.

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

Рисунок 11 – Результат публикации

Рисунок 12 – Список библиотек
Создание веб-интерфейса
Для управления используется одна веб-страница index.html с простым интерфейсом. Используются две кнопки (запуск и остановка работы скрипта) и отдельное поле для вывода информации. Для работы с JavaScript подключается библиотека jQuery.

Рисунок 13 – подключение библиотеки jQuery
Библиотека используется для добавления обработчиков событий на кнопки. При нажатии на кнопки выполняются AJAX-запросы к серверу. При нажатии на кнопку «Запустить скрипт» отправляется POST-запрос на сервер по адресу /start. Если запрос успешен, выводится статус и запускаются функции для получения вывода и сообщений. В случае ошибки выводится сообщение об ошибке. Аналогично, при нажатии на кнопку «Остановить скрипт» отправляется POST-запрос на /stop.
fetchMessages() – получает сообщения с помощью GET-запроса к /messages и обновляет область сообщений на странице. Отдельная функция обеспечивает вызов данной функции через определенный интервал.

Рисунок 14 – скрипты для реагирования на кнопки и вывода сообщений
В качестве основного приложения используется файл с кодом Flask, который обеспечивает запуск html-страницы и файла парсера. В процесс работы отслеживаются нажатия кнопок, а также перехватывается информация от скрипта парсера, вывод перенаправляется на страницу через отдельную переменную. Для отслеживания текущего статуса используется переменная process, это позволяет выводить уведомления о попытке повторного запуска или остановки скрипта. Основные библиотеки:
— subprocess. Позволяет запускать новые процессы, подключаться к их входным/выходным потокам;
— threading. Используется для управления потоками;
— os и signal. Используются для взаимодействия с операционной системой, включая управление процессами;
— time. Используется для задержек в выполнении.

Рисунок 15 – Используемые библиотеки
Также предусмотрены глобальные переменные:
— process. Хранит объект процесса, запущенного с помощью subprocess;
— messages: Список для хранения сообщений, полученных от скрипта.
Функция run_script обеспечивает запуск основного скрипта. subprocess.Popen — запускает внешний скрипт mob25_test.py в отдельном процессе. Параметр stdout=subprocess.PIPE позволяет захватывать стандартный вывод этого процесса, что обеспечивает вывод информации на HTML-страницу. Далее стартует бесконечный цикл. Каждую секунду читается строка из вывода скрипта. Если строка не пустая, она декодируется (кодировка CP1251) и добавляется в список messages.
Маршрут /start обрабатывает POST-запросы на /start. Предусмотрена проверка, не запущен ли уже процесс. Если он не запущен, создается новый поток, который запускает функцию run_script(). Возвращает статус выполнения в формате JSON.

Рисунок 16 – запуск скрипта
Маршрут /stop. Нажатие на кнопку остановки, завершение парсинга. Обрабатывает POST-запросы на /stop. Проверяется, запущен ли процесс. Если да, посылается сигнал SIGTERM для его завершения и обнуляется переменная process.

Рисунок 17 – остановка скрипта
/messages – вывод данных на HTML страницу. Для этого используется стандартный print в исходном скрипте. Обрабатывает GET-запросы на /messages. Возвращает список сообщений, собранных из вывода скрипта, в формате JSON.

Рисунок 18 – вывод данных.
Для запуска нового файла в виде отдельного процесса используется библиотека subprocess. Она позволяет управлять запуском скрипта и перехватывать данные для вывода. После запуска скрипта стартует бесконечный цикл, в котором постоянно отслеживается вывод новых данных. При обнаружении вывода информация построчно записывается в список messages.
При запуске основного маршрута также обеспечивается загрузка HTML-страницы.

Рисунок 19 – загрузка HTML-страницы
HTML-страница представляет собой простой интерфейс с двумя кнопками, в нижней части находится блок вывода информации.

Рисунок 20 – вывод информации о работе парсера
Тестирование работы в реальных условиях
Основными целями тестирования парсера были:
— проверка корректности извлечения данных о книгах (название, автор, жанр, цена и т.д.);
— оценка производительности парсера при работе с большим объемом данных;
— выявление и устранение ошибок и недочетов в коде;
— обеспечение устойчивости работы парсера в различных условиях (например, при нестабильном интернет-соединении);
— корректная обработка ситуаций, когда определенные элементы отсутствовали на исходной странице.
Парсер реализован на Python с использованием библиотек requests для HTTP-запросов и BeautifulSoup для парсинга HTML-кода. Он выполняет следующие шаги:
— отправка GET-запроса на целевой веб-сайт;
— получение HTML-кода страницы;
— извлечение необходимых данных с помощью CSS-селекторов;
— сохранение полученной информации в переменные для последующей публикации на другом сайте.
Тестирование осуществлялось в реальном режиме и было разбито на несколько этапов
Функциональное тестирование:
— проверка корректности извлечения данных. Для этого в текстовый файл было добавлено несколько категорий каталога из которых загружались книги;
— сравнение результатов работы парсера с ожидаемыми данными. Визуально проверяется, что фильтры сработали корректно (язык, тип книги, и так далее). Также вручную проверяется компоновка на конечной странице. К примеру, если у книги несколько авторов, такое событие обрабатывается отдельно. Авторы собираются в отдельный список, далее последовательно добавляются в нужную переменную для корректного вывода. Если автор не указан, блок не выводится, при этом расположение других компонентов остается корректным.
Тестирование производительности:
— измерение времени выполнения парсера при обработке 100, 500 и 1000 книг;
— оценка нагрузки на сервер при одновременном выполнении нескольких запросов;
Работа в реальных условиях показала, что в данной связке самым узким местом является конечный сайт. Массовая публикация записей приводит к повышению нагрузки на оборудование хостера. Достаточно быстро можно получить превышение лимита в рамках текущего тарифа. При необходимости можно снизить нагрузку, полностью поменяв режим публикацию на прямую выгрузку подготовленного предварительно контента в базу данных. На графике ниже отображена нагрузка в процессе тестирования – виден резкий всплеск с фиксацией превышения суточного лимита. Однако далее работа была уже в штатном режиме – нагрузка практически минимальна. Это означает, что скрипт не будет влиять на работу сайта даже при работе без перерыва.

Рисунок 21 – Превышение нагрузки на хостинг сайта (база данных)
В данной реализации каждая запись публикуется отдельно. Однако в изначальных требованиях к проекту указано, что будет использоваться низкая скорость публикации. Будут отслеживаться только новинки и популярные публикации в одном разделе, который включает 10 подразделов. Поэтому такая оптимизация не потребовалась.
Тестирование устойчивости:
— имитация нестабильного интернет-соединения: отключение сети во время выполнения запросов и проверка обработки исключений;
— имитация ситуации, когда исходная страница не получена. В этом случае просто инициируется новая пауза, после которой отправляется повтор.
Общий алгоритм работы подразумевает, что если запись по определенным причинам не удалось перенести, то идентификатор книги не добавляется в итоговый список. В результате при следующем обходе списка будет осуществлена новая попытка добавления.
При полной потере связи скрипт останавливается с выводом соответствующего сообщения.
В процессе тестирования были выявлены несколько мелких недочетов в коде:
— неправильная обработка исключений. В некоторых случаях парсер не обрабатывал исключения, связанные с отсутствием элементов на странице. Оказалось, что для некоторых книг не указывается автор или код ISBN. При отсутствии элемента скрипт завершался с ошибкой, хотя достаточно просто пропустить элемент. Это было исправлено добавлением дополнительных проверок перед извлечением данных. Также такая проверка осуществляется в процессе сборки конечного блока перед публикацией. Это необходимо, чтобы не было пустых мест.
Тестирование разработанного парсера для сканирования каталога книг показало его высокую эффективность и стабильность в работе. Были выявлены и устранены мелкие недочеты, что позволило улучшить качество кода и повысить надежность программы. В дальнейшем планируется проводить регулярное тестирование после внесения изменений в код, а также расширить функциональность парсера для работы с другими источниками данных.
Публикация на сервере
После тестирования на локальной машине можно переходить к публикации на выбранном сервере. Для подключения используется утилита PuTTY. Основные файлы проекта можно сразу загрузить на хостинг через веб-интерфейс. После подключения по SSH необходимо запустить новый контейнер и установить нужную версию Python.
PuTTY – это мощный и удобный клиент для подключения к удалённым серверам через протоколы SSH, Telnet и другие. Он стал популярным инструментом среди системных администраторов и разработчиков благодаря своей простоте и функциональности. Позволяет устанавливать безопасные соединения, что особенно важно для работы с удаленными системами.
С помощью PuTTY пользователи могут выполнять команды на сервере, передавать файлы и управлять приложениями. Интерфейс программы интуитивно понятен: после ввода адреса сервера и порта достаточно нажать кнопку «Open», чтобы начать сессию. Поддерживает ключевую аутентификацию, что повышает безопасность соединений.

Рисунок 22 – Основной интерфейс программы PuTTY
Кроме того, приложение предлагает множество настроек: можно изменять шрифты, цвета, параметры прокси и сохранять профили для быстрого доступа к различным серверам. PuTTY доступен для Windows, а также существует множество портов для Unix-подобных систем, что делает его универсальным инструментом для работы в различных средах.
Для публикации в рамках текущего аккаунта Beget был запущен отдельный виртуальный сервер в облаке. Это заметно упрощает дальнейшую работу.

Рисунок 23 – Параметры созданного сервера
Файлы проекты загружаются в созданный каталог через штатный проводник хостинга.

Рисунок 24 – файлы проекта на хостинге
Дальнейшая работа осуществляется через утилиту PuTTY. Интерпретатор Python уже присутствует в операционной системе, поэтому этап подготовки подразумевает только установку библиотек через текстовый файл requirements.txt.
Файл requirements.txt в проектах на Python служит для указания зависимостей, необходимых для работы приложения. Он содержит список библиотек и их версий, которые можно установить с помощью менеджера пакетов pip. Это упрощает процесс установки необходимых пакетов, особенно при развертывании проекта на новом окружении или сервере.
Чтобы создать файл requirements.txt, можно использовать штатную команду:
pip freeze > requirements.txt
Эта команда сохранит текущие установленные библиотеки и их версии в файл.
Для установки библиотек из существующего файла requirements.txt используется следующая команда:
pip install -r requirements.txt
Эта команда прочитает файл и установит все перечисленные в нем зависимости. Таким образом, requirements.txt обеспечивает простоту и удобство управления библиотеками в проектах на Python.

Рисунок 25 – Сгенерированный файл requirements.txt
Для запуска скрипта используется стандартная команда для файлов Python. После этого веб-интерфейс становится доступным по адресу http://62.217.181.75:5000/, книги публикуются в разделе https://mob25.com/category/knigi/

Рисунок 26 – Запуск основного файла

Рисунок 27 – Работа парсера на сервере
Полученный результат
Партнерский магазин – это платформа, на которой владельцы сайтов размещают ссылки на товары или услуги других компаний. Когда пользователь переходит по такой ссылке и совершает покупку, владелец сайта получает комиссию. Это создает взаимовыгодное сотрудничество между продавцом и партнером, позволяя каждому участнику процесса получать свои выгоды.
С увеличением трафика естественным образом растет и доход. Партнерский маркетинг позволяет зарабатывать на продаже товаров, даже если вы не являетесь производителем или продавцом. Благодаря проделанной работе по созданию привлекательного контента и грамотному выбору партнеров, многие владельцы сайтов уже начали получать стабильный доход. Это создает ощущение финансовой независимости и дает возможность инвестировать в дальнейшее развитие проекта.
Поскольку контент уже предоставляется самой компанией, запустить такой проект достаточно просто. Однако это приводит к сильной конкуренции. Для популярных направлений могут запускаться сотни сайтов с идентичным контентом.
Практика показывает, что поисковые системы активно стараются бороться с такими ресурсами, поскольку одинаковый контент снижает ценность сайта в целом. Несмотря на наличие негативных факторов, данное направление при правильном подход может дать неплохой результат. Даже с минимальной оптимизацией такой ресурс может приносить заметную прибыль.

Рисунок 28 – Правила партнерской программы Литрес
Уже в первый месяц после запуска партнерского магазина появляется результат. Есть переходы из основных поисковых систем, появились первые продажи и начисления. Такой результат показывает, что при дальнейшем развитии сайта можно постепенно улучшать показатели и увеличивать полученную прибыль.

Рисунок 29 – Статистика продаж книг по дням
Вывод
Результатом выполнения работы является готовый парсер, заточенный под определенную задачу. Обеспечивается парсинг книг из определенных разделов каталога Литрес с последующей публикацией на стороннем сайте. Выделены все основные требования к проекту, все они реализованы. Скрипт может работать в постоянном режиме, отслеживая публикации в определенных категориях.
При обнаружении книги, которая подходит по параметрам и не была ранее опубликована, приложение извлекает нужные данные и публикует их на втором сайте.
В процессе работы над проектом были проанализированы современные технологии, позволяющие создавать полноценные парсеры с нужным набором функций. Для работы был выбран язык программирования Python и микрофреймворк Flask. Основной функционал реализован при помощи выбранных библиотек.
Создана простая веб-страница, которая позволяет запускать и останавливать основной скрипт и получать в удобном виде результаты работы. Проект развернут на выбранном сервере, обеспечена работа в круглосуточном режиме.
Было проведено полноценное тестирование работы в разном режиме. Это позволило выявить и устранить недочеты, а также оценить нагрузку на сервер Бегет. Обеспечена полноценная защита от блокировки со стороны каталога Литрес в процессе массового парсинга контента.
При необходимости код можно быстро адаптировать под другие задачи. К примеру, можно добавить новые источники данных (сайты), что позволит расширить ассортимент. Также можно расширить набор площадок для публикации партнерского контента. Есть готовые библиотеки для автоматической публикации в популярных социальных сетях, группе Telegram и так далее.
Код HTML-страницы
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Управление скриптом</title> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <link rel="stylesheet" href="styles.css"> <!-- Подключаем внешний CSS файл --> </head> <body> <h1>Управление Python-скриптом</h1> <button id="start-btn">Запустить скрипт</button> <button id="stop-btn">Остановить скрипт</button> <br><br><h2>Сообщения от парсера:</h2> <div id="messages"></div> <script> $(document).ready(function() { $('#start-btn').click(function() { $.post('/start', function(data) { alert(data.status); fetchOutput(); fetchMessages(); }).fail(function(data) { alert(data.responseJSON.status); }); }); $('#stop-btn').click(function() { $.post('/stop', function(data) { alert(data.status); }).fail(function(data) { alert(data.responseJSON.status); }); }); function fetchMessages() { $.get('/messages', function(data) { $('#messages').empty(); data.messages.forEach(function(message) { $('#messages').append('<div>' + message + '</div>'); }); }); } setInterval(function() { fetchMessages(); }, 5000); }); </script> </body> </html>
Код Flask
from flask import Flask, jsonify, render_template import subprocess import threading import os import signal import time app = Flask(__name__) process = None messages = [] def run_script(): global output global process global messages process = subprocess.Popen(['python', 'mob25_test.py'], stdout=subprocess.PIPE) while True: time.sleep(1) line = process.stdout.readline() if not line: break messages.append(line.decode('cp1251')) @app.route('/') def index(): return render_template('index.html') @app.route('/start', methods=['POST']) def start_script(): global process if process is None or process.poll() is not None: thread = threading.Thread(target=run_script) thread.start() return jsonify({"status": "Парсинг запущен успешно"}), 200 else: return jsonify({"status": "Парсинг запущен ранее"}), 400 @app.route('/stop', methods=['POST']) def stop_script(): global process if process is not None and process.poll() is None: os.kill(process.pid, signal.SIGTERM) process = None return jsonify({"status": "Парсинг остановлен"}), 200 else: return jsonify({"status": "Парсинг не запущен"}), 400 @app.route('/messages', methods=['GET']) def get_messages(): return jsonify({"messages": messages}), 200 if __name__ == '__main__': app.run(debug=True)
Основной код парсера
client = Client('https://mob25.com/xmlrpc_xxx.php', 'логин', 'пароль') count_wp = 0 count_vk = 0 vk_limit = False ch_n = '\n' options = '?art_types=text_book&art_types=audiobook&languages=ru' ref = '?lfrom=477110899' print('Старт парсинга') with open("book_pk_20.txt", "r", encoding="utf-8") as file_cl: category_list = file_cl.read().split('\n') with open("id_wp.txt", "r", encoding="utf-8") as file_id: id_wp = file_id.read().split('\n') file_id.close() random.shuffle(category_list) count_cat = len(category_list) + 1 req = requests.get("https://sp.litres.ru/genres_list_2/", headers=headers, cookies=cookies) req = req.text soup_cat = BeautifulSoup(req, "lxml") for category in category_list: end_time = time.time() start_time = time.time() count_cat -= 1 try: name_category = (soup_cat.find( attrs={"id": (category.split('/'))[0]}))['title'] except: print('Ошибка названия категории') continue name_category = name_category[0].upper() + name_category[1:] print('Текущая категория - ', name_category) print(f'Осталось категорий - {count_cat}', ) print(f'Опубликовано книг - {count_wp}') print('---------', end='\n\n', flush=True) sleep(3) req = requests.get(f'https://api.litres.ru/foundation/api/genres/{category}\ &art_types=text_book&art_types=audiobook&languages=ru&\ languages=en', headers=headers) src = req.text try: data_category = json.loads(src) except: continue list_href = [] try: a = len(data_category['payload']['data']) except: continue for i in range(len(data_category['payload']['data'])): list_href.append(data_category['payload']['data'][i]['url']) for href in list_href: title, author, id, isbn = '', '', '', '' id = ((href.split('-'))[-1])[:-1] id = id.split('/')[0] try: req = requests.get(f"https://api.litres.ru/foundation/api/arts/{id}\ /reviews?limit=10&o=popular&offset=0", headers=headers, cookies=cookies) except: print('Литрес пауза') sleep(10) src_api = req.text try: data = json.loads(src_api) except: continue try: a = len(data['payload']['data']) except: continue if len(data['payload']['data']) == 0: continue try: req = requests.get(f"https://www.litres.ru{href}", headers=headers, cookies=cookies,) except: sleep(30) req = requests.get(f"https://www.litres.ru{href}", headers=headers, cookies=cookies,) src = req.text soup = BeautifulSoup(src, "lxml") if soup.find("h1"): title = soup.find("h1").text else: sleep(10) continue if soup.find(class_="Authors_authors__7_HQN"): count_author = soup.find( class_="Authors_authors__7_HQN").find("h4").text isbn = soup.find("span", itemprop="isbn") if isbn: isbn = isbn.text if soup.find(class_="BookAuthor_author__info__5eDIs"): author = soup.find("div", class_="Truncate_truncated__jKdVt" ).find_all("span", itemprop="name") for i in range(len(author)): if author[i]: author[i] = author[i].text author = ', '.join(map(str, author)) try: description = soup.find( class_="BookCard_truncate__jrVwM").find_all('p') except: print('нет опиcания') continue for i in range(len(data['payload']['data']) - 1, -1, -1): author_k = data['payload']['data'][i]['user_display_name'] text_k = data['payload']['data'][i]['text'] id_k = data['payload']['data'][i]['id'] date_k = data['payload']['data'][i]['created_at'] date_k = (datetime.strptime(date_k, '%Y-%m-%dT%H:%M:%S' ).timestamp()) if id not in id_wp: wpcontent = '' wpcontent += '<!-- wp:paragraph -->' wpcontent += ''.join(map(str, description)) wpcontent += '<!-- /wp:paragraph -->' wpcontent += '<!-- wp:paragraph -->' if author: wpcontent += f'<p>{count_author}: {author}<br></p>' if isbn: wpcontent += f'<p>ISBN: {isbn}<p>' wpcontent += '<!-- /wp:paragraph -->' wpcontent += '<!-- wp:paragraph -->' wpcontent += f'<a href="https://www.litres.ru{href}{ref}"\ target="_blank" rel="noreferrer noopener">Скачать книгу\ </a></p><br>' id_wp.append(id) with open("id_wp.txt", "a", encoding="utf-8") as file_id: file_id.write(f'{id}\n') post = WordPressPost() post.terms_names = {'category': [name_category], } post.title = title post.content = (wpcontent) post.post_status = 'publish' post.comment_status = 'open' post.id = client.call(posts.NewPost(post)) my_latest_post = client.call(posts.GetPost(post.id)) link_wp = my_latest_post.link count_wp += 1 sleep(60)