Высокоуровневый Ruby-фреймворк для краулинга веб-страниц
Vessel — это быстрый высокоуровневый фреймворк с открытым исходным кодом для сканирования и получения данных с веб-страниц, созданный на основе Ferrum — драйвера с минимальным количеством зависимостей, написанного на чистом Ruby, для запуска headless Google Chrome.
Веб-краулер — это инструмент, который используется для сбора информации с публичных или приватных веб-страниц. Он используется аналитиками, поисковыми движками, скоринг-системами банков и т.д. Везде, где нужен автоматический сбор информации из публичных ресурсов, когда информация представлена не в машиночитаемом формате.
Начало работы
Лучший способ продемонстрировать возможности Vessel — сделать это на примере. Не волнуйтесь, большое количество возможностей не делает его трудным в использовании.
Для начала добавьте Vessel в свой Gemfile:
gem "vessel"
Теперь давайте создадим crawler class. Создайте spider.rb
, в котором мы определим Spider
class, производный от Vessel::Cargo
. Настройте параметры краулинга и пропишите callback-метод для парсинга, который будет вызываться для каждой найденной страницы (если вы не предоставите такой метод, то Vessel::Cargo
вызовет NotImplementedError
, когда страница будет найдена). Код для этого ниже:
require "vessel"
class Spider < Vessel::Cargo
domain "blog.scrapinghub.com"
start_urls "https://blog.scrapinghub.com"
def parse
css(".post-header>h2>a").each do |a|
yield request(url: a.attribute(:href), method: :parse_article)
end
css("a.next-posts-link").each do |a|
yield request(url: a.attribute(:href), method: :parse)
end
end
def parse_article
yield page.title
end
end
Spider.run { |title| puts title }
Большая часть этого процесса довольно очевидна. Что происходит «за кулисами»: Vessel использует пул потоков для выполнения запросов, по умолчанию используя один поток на ядро (вы можете это изменить, добавив threads max: n
в определение класса).
Краулер запускается при помощи:
bundle exec ruby spider.rb
Результатом будет заголовок каждой страницы, в том виде, в котором Chrome сканирует его, парсит и передает обратно в Ruby class.
Быстрый, как Chrome, невероятно простой и расширяемый
Из примера видно, как легко делать поиск, используя методы Ferrum DOM: извлекать структурированные данные из обычно неструктурированных веб-страниц.
Пример кода выше просто ищет (через request
) два разных вида ссылок (которые определяются их стилевыми CSS селекторами) и не берёт во внимание всё остальное, за исключением заголовка страницы, который выводится как результат. Но здесь вы можете сделать извлечение любой информации на ваш выбор.
И хотя скрейпинг является мощным инструментом, поиск с помощью краулинга даёт вам гораздо больше возможностей. Вместо того, чтобы ограничиваться поиском по отдельным страницам, Vessel позволяет извлекать данные сразу по всему сайту или даже нескольким сайтам, предоставляя вам полный контроль над тем, по каким ссылкам идет поиск, какие данные возвращаются на протяжении всего процесса, и что вы будете с ними делать в дальнейшем. Нужно создать CSV с сопоставленными табличными данными? Никаких проблем. Или вывести JSON, который вы можете вставить где-то ещё? Тоже легко.
Фактически, с помощью Vessel и Ferrum вы можете сканировать, парсить, извлекать и преобразовывать веб-контент настолько просто, что вы удивитесь, почему вы раньше делали это по-другому!