Создание простого веб-скрейпера на Ruby

Введение

Один из лучших способов доступа к данным сайта  —  через его API (интерфейс прикладного программирования). Но что, если у сайта нет API? Тогда стоит задействовать веб-скрейпинг. В этой статье мы пошагово разберем процесс создания простого веб-скрейпера с использованием Ruby. А кроме того, рассмотрим более сложные ситуации, в которых применяется веб-скрейпинг.

В качестве примера возьмем сайт Atlas Obscura: будем получать доступ к содержащейся на нем информации.

Настройка среды

Первым делом настроим среду для скрейпинга. Для этого используем модуль Open-URI и библиотеку Nokogiri  —  они задействуются в Ruby для скрейпинга данных. Сначала надо установить open-uri и nokogiri, а затем с помощью метода require затребовать их в файле, который будет использоваться для написания кода скрейпинга. Не будет лишним затребовать таким же образом библиотеку pry для добавления в код binding.pry, с помощью которого будет проверяться, работает ли код.

Для простого веб-скрейпера создаем два класса Ruby: Scraper и Place. Класс Scraper задействуется для выполнения всей тяжелой работы  —  получения данных с сайта Atlas Obscura и создания экземпляров класса Place. Класс Place довольно простой, в нем содержатся методы считывания и задания нужных нам атрибутов, а также методы для хранения новых экземпляров:

Кроме того, чтобы с помощью класса Scraper инстанцировать класс Place, нужно в файле scraper.rb посредством метода require затребовать place.rb:

Этапы создания веб-скрейпера

Настроив среду и файлы, будем приступать к скрейпингу. Для завершения процесса создания простого скрейпера проходим эти три этапа:

  1. Чтобы заполучить HTML сайта, задействуем nokogiri и open-uri.
  2. Чтобы заполучить нужные атрибуты для экземпляров класса Place, задействуем селекторы CSS.
  3. Создаем методы, которые инстанцируют новые экземпляры класса Place и присваивают атрибуты.

Первый этап процесса довольно прост: используем метод open из nokogiri и open-uri, чтобы заполучить HTML и задать его в виде переменной doc.

Задействование binding.pry для открытия сеанса pry и распечатки переменной doc дает такой вывод HTML:

Чтобы заполучить конкретные HTML-элементы для атрибутов, нужно знать их селекторы CSS. Для этого задействуется инспектор элементов в консоли браузера.

На этом этапе потребуется действовать методом проб и ошибок, досконально изучив все, чтобы получить абсолютно правильные элементы. Для этого придется поработать с селектором элементов в браузере и посмотреть, как определяется каждый элемент, а затем протестировать различные селекторы CSS в терминале.

В сеансе pry доступ к элементам получается с помощью методов .css и .text. Например, при запуске doc.css(“.Card”).first.text в ходе тщательного анализа HTML-документа захватываются все элементы с классом CSS Card, затем возвращается первый объект в этом массиве, после чего этот объект выдается в виде обычного текста. Дальше при желании детализируем, добавив еще селекторов CSS, например так: doc.css(“.Card”).first.css(“h3”).text.

Заметим опять же, что для получения правильных селекторов CSS на этом этапе придется много работать методом проб и ошибок и запастись терпением. А на более сложных сайтах порой потребуется использование более специфических селекторов CSS.

Разобравшись с селекторами CSS для нужных нам атрибутов, приступим к написанию методов для присвоения HTML-элементов экземпляру Place, а затем к выводу списка экземпляров Place:

Добавив к коду внизу Scraper.new.print_places, при запуске этого файла в терминале получим список экземпляров Place. Вот как выглядит конечный вывод:

Заключение

В целом веб-скрейпинг  —  отличный инструмент, хотя для его правильного применения надо немало потрудиться. Легкодоступный и удобный в использовании API (при его наличии на сайте) явно предпочтительнее, нежели задействовать веб-скрейпинг. Тем более что последний сильно зависит от содержащегося на сайте HTML, в который внести изменения не составляет большого труда.

Однако у веб-скрейпинга есть одна очень крутая особенность: он позволяет не только создавать экземпляры классов Ruby, но и экспортировать данные в различных форматах, в том числе .csv и JSON. Эта функциональность дает веб-разработчикам возможность извлекать с сайтов общедоступные данные, сохранять эту информацию в формате JSON, а затем использовать ее для расширения API собственной серверной части, что в конечном итоге позволяет другим разработчикам легко получать доступ к данным, не прибегая к веб-скрейпингу!

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Victoria Perkins: Making a simple web scraper in ruby

Предыдущая статьяВизуализация стратегии автоматизированного тестирования
Следующая статья4 совета Python Django разработчику