CoderCastrov logo
CoderCastrov
Парсер

Парсинг результатов поиска — простой хак с использованием Python

Парсинг результатов поиска — простой хак с использованием Python
просмотров
3 мин чтение
#Парсер

Практический пример с кодом на Python

Бизнес-контекст

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

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

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

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

Распределение Парето

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

Уменьшение размерности данных

Чтобы сделать проблему с длинным хвостом управляемой, я хотел уменьшить размерность данных. Например, если бы были транзакции с 10 000 предприятий (каждое из которых было рестораном, но мы об этом не знали), вместо исследования и категоризации каждого названия предприятия как "ресторан" мы могли бы вместо этого искать их описание предприятия в Интернете; затем эти 10 000 предприятий могли бы быть правильно категоризированы как "ресторан", проверяя наличие (скажем) всего 10 ключевых слов в их описании, таких как "ресторан", "паста", "пицца", "еда", "обед" и т. д.

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


Техническое задание

Передо мной стояла двойная задача: (a) найти способ парсить результаты поиска и (b) сделать это надежным, чтобы мы могли запускать пакетные запросы без блокировки поисковой системой из-за необычного трафика.

Часть #1 — Парсинг результатов поиска

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

  • Создать URL и загрузить веб-страницу (здесь я использую Google в качестве примера)
  • Использовать библиотеку Beautiful Soup для разбора HTML-страницы
  • Найти соответствующий тег для нужной информации

Поиск правильного тега и извлечение информации из него зависит от конкретной веб-страницы и требует некоторой итерации.

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

Часть №2 — Выполнение запросов без блокировки

Исследование (т.е. просмотр множества страниц Stack Overflow)

Большинство предложений сводилось к использованию какого-то вида 'user-agent' в запросе, чтобы сделать его похожим на запросы, инициированные веб-браузером вручную, а не автоматически из программы. Фактически, существуют библиотеки на Python, которые позволяют вам переключаться между несколькими такими user-agent в вашем коде.

Простой, но эффективный хак!

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

Идея заключалась в том, чтобы периодически сбрасывать и обновлять IP-адрес машины, прежде чем веб-сайт обнаружит необычный трафик и начнет блокировать запросы.

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

(Отказ от ответственности: Пожалуйста, относитесь к скрапингу ответственно и ознакомьтесь с условиями использования конкретного веб-сайта перед скрапингом.)


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

Ссылки, для любознательных: