07.04.2024: Эта статья изначально была опубликована на habr.com и была просмотрена там 31 тысячу раз. Но теперь я решил перенести её в свой блог.
От переводчика: Оригинал статьи Advanced web scraping with Mechanize
Обзор
В предыдущей записи я описал основы - введение в веб парсинг на Ruby. В конце поста, я упомянул инструмент Mechanize, который используется для продвинутого парсинга.
Данная статья объясняет как делать продвинутый парсинг веб-сайтов с использованием Mechanize, который, в свою очередь, позволяет делать отличную обработку HTML, работая над Nokogiri.
Парсинг обзоров с Pitchfork
Mechanize из коробки предоставляет инструменты, которые позволяют заполнять поля в формах, переходить по ссылкам и учитывать файл robots.txt. В данной записи, я покажу как это использовать для получения последних обзоров с сайта Pitchfork.
Вы всегда должны парсить аккуратно. Прочитайте статью Is scraping legal? из блога ScraperWiki для ознакомления с обсуждениями на эту тему.
Отзывы разделены на несколько страниц, поэтому, мы не можем просто взять одну страницу и разобрать её с помощью Nokogiri. Здесь то нам и понадобится Mechanize с его способностью кликать на ссылки и переходить по ним на другие страницы.
Установка
Вначале нужно установить сам Mechanize и его зависимости через Rubygems.
Можно приступить к написанию нашего парсера. Создадим файл scraper.rb
и добавим в него некоторые require
. Это укажет на зависимости, которые необходимы для нашего скрипта. date
и json
это части стандартной библиотеки ruby, так что дополнительно устанавливать их нет необходимости.
Теперь мы можем начать использовать Mechanize. Первое, что нужно сделать, это создать новый экземпляр класса Mechanize (agent
) и использовать его, чтобы скачать страницу (page
).
Находим ссылки на обзоры
Теперь мы можем использовать объект page
, чтобы найти ссылки на обзоры.
Mehanize позволяет использовать метод .links_with
, который, как следует из названия, находит ссылки с указанными атрибутами. Здесь мы ищем ссылки, которые соответствуют регулярному выражению.
Это вернет массив ссылок, но нам нужны только ссылки на обзоры, не пагинация. Чтобы удалить ненужное мы можем вызвать .reject
и отбросить ссылки, похожие на пагинацию.
В показательных целях и чтобы не нагружать сервера Pitchfork, мы будем брать ссылки только на первые 4 обзора.
Обработка каждого обзора
Мы получили список ссылок и хотим обработать каждую в отдельности, для этого мы будем использовать метод .map
и возвращать хеш после каждой итерации.
Объект page
имеет метод .search
, который делегируется методу .search
Nokogiri. Это означает, что мы можем использовать CSS селектор как аргумент для .serach
и он вернет массив совпавших элементов.
Сначала мы возьмем метаданные обзора, используя CSS селектор #main .review-meta .info
, а затем будем искать внутри review_meta
элемента кусочки информации, которая нам нужна.
Теперь мы имеем массив хешей с обзорами, который мы можем, например, вывести в JSON формате.
Все вместе
Скрипт полностью:
Сохранив этот код в нашем файле scraper.rb
и запустив его командой:
Мы получим, что-то похожее на это:
Если хотите, вы можете перенаправить эти данные в файл.
Заключение
Это только вершина возможностей Mechanize. В этой статье я даже не коснулся способности Mechanize заполнять и отправлять формы. Если вам это интересно, то я рекомендую почитать руководство Mechanize и примеры использования.
Много людей в комментариях к предыдущему посту сказали, что я должен был просто использовать Mechanize. Хотя я согласен, что Mechanize является отличным инструментом, тот пример, который я привел в первой записи на эту тему был простым, и использование в нем Mechanize, как мне кажется, является излишним.
Однако, учитывая способности Mechanize, я начинаю думать, что даже для простых задач парсинга, зачастую, будет лучше использовать именно его.
Все статьи серии:
- Веб-парсинг на Ruby
- Продвинутый парсинг веб-сайтов с Mechanize (вы здесь)
- Использование morph.io для веб-парсинга