Веб-скрапинг с помощью Ruby: Полное руководство

Независимо от того, начинающий вы или опытный программист, это руководство предоставит вам знания, необходимые для того, чтобы стать эффективным веб-скрапером на Ruby.
3 min read
Web Scraping with Ruby

Этот руководство научит вас правильно извлекать данные с сайта с использованием Ruby и объяснит, почему это один из самых эффективных языков программирования для веб-скрапинга.

В данном руководстве будут рассмотрены:  

Подходит ли Ruby для веб-скрапинга?

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

В частности, Ruby является отличным выбором для веб-скрапинга благодаря широкому спектру доступных библиотек от сторонних разработчиков. Их еще называют «драгоценными камнями», позволяющими решить практически любую задачу. Если речь идет о программном извлечении информации из интернета, существуют библиотеки для загрузки страниц, анализа их HTML-содержимого и извлечения из них данных.

В общем, веб-скрапинг с помощью Ruby не только возможен, но и предельно прост благодаря множеству доступных библиотек. Давайте узнаем, какие из них являются наиболее популярными!

Лучшие библиотеки Ruby для веб-скрапинга

Вот три лучшие библиотеки для веб-скрапинга с помощью Ruby:

  • Nokogiri: Надежная и гибкая библиотека для веб-скрапинга HTML и XML с полным API для просмотра и манипулирования документами, что позволяет легко извлекать из них необходимые данные.
  • Mechanize: Библиотека с функциями «безголового» браузера, предоставляющая высокоуровневый API для автоматизации взаимодействия с сайтами. Может хранить и отправлять куки, работать с перенаправлениями, переходить по ссылкам и отправлять формы. Кроме того, она сохраняет историю для отслеживания посещенных сайтов.
  • Selenium: Самый популярный фреймворк для выполнения автоматизированных тестов. Способен заставить браузер взаимодействовать с сайтом так, как это бы сделал настоящий пользователь. Эта технология играет ключевую роль в обходе решений по борьбе с ботами для сканирования сайтов, которые используют JavaScript для рендеринга или получения данных.

Предустановки

Прежде чем писать код, необходимо установить на свою машину Ruby. Следуйте приведенной ниже процедуре, относящейся к вашей операционной системе.

Установите Ruby на macOS

 

По умолчанию Ruby уже установлен в macOS, начиная с версии 10.11 (El Capitan), выпущенной в 2015 году. Учитывая, что macOS интегрировал Ruby для обеспечения некоторой функциональности, не стоит его трогать. Обновлять родную версию Ruby с помощью команд brew install ruby или update ruby mac не рекомендуется, так как это может сломать некоторые встроенные функции.

Установите Ruby на Windows

 

Загрузите пакет RubyInstaller, запустите его и следуйте указаниям мастера установки, чтобы установить Ruby. Может потребоваться перезагрузка системы. Начиная с Windows 10, вы также можете использовать подсистему Windows для Linux для установки Ruby по инструкции ниже.

Установите Ruby в Linux

 

Лучший способ настроить среду Ruby в Linux — установить его с помощью менеджера пакетов.

В Debian и Ubuntu запустите:

sudo apt-get install ruby-full

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

Независимо от того, какая у вас ОС, теперь вы можете убедиться, что Ruby работает с ней:

ruby -v

Должно получиться что-то вроде:

ruby 3.2.2 (2023-03-30 revision e51014f9c0)

Отлично! Теперь вы готовы приступить к работе с веб-скрапингом на Ruby!

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

В этом разделе вы узнаете, как создать веб-скрапер на языке Ruby. Этот автоматизированный скрипт будет извлекать данные с главной страницы Bright Data. В частности, он будет:  

  • Подключитесь к целевому сайту
  • Выберите интересующие вас элементы HTML из DOM
  • Извлеките из них данных
  • Преобразуйте собранные данные в удобные для изучения форматы — такие, как CSV или JSON

На момент написания статьи это то, что видят пользователи при посещении целевой страницы:

Примите во внимание, что домашняя страница BrightData часто меняется и к тому моменту, когда вы будете читать эту статью, она может уже слегка видоизмениться.

Конкретная цель веб-скрапинга — получить информацию, содержащуюся в следующих карточках:  

Домашняя страница BrightData

Следуйте приведенному ниже пошаговому руководству и узнайте, как выполнять веб-скрапинг с помощью Ruby!

Шаг 1: Инициализация проекта Ruby

Прежде чем приступить к работе, необходимо настроить ваш проект Ruby. Запустите терминал, создайте папку проекта и войдите в нее с помощью:

mkdir ruby-web-scraper

cd ruby-web-scraper

Каталог ruby-web-scraper будет содержать ваш скрапер.

Затем инициализируйте файл scraper.rb в папке проекта со следующим содержимым:

puts "Hello, World!"

Приведенный выше фрагмент — самый простой Ruby-скрипт из возможных.

Убедитесь, что он работает, запустив его в терминале:

ruby scraper.rb

При этом должно быть выведено следующее сообщение:

Hello, World!

Пора импортировать ваш проект в IDE и внедрить в него продвинутую логику веб-скрапинга на Ruby! В этом руководстве вы увидите, как настроить Visual Studio Code (VS Code) для разработки на Ruby. Однако подойдет и любая другая Ruby IDE.

Поскольку VS Code не поддерживает Ruby нативно, сначала необходимо добавить расширение Ruby. Запустите Visual Studio Code, нажмите на значок “Расширения” в левой панели и введите “Ruby” в поисковой строке сверху.

Расширения

Нажмите на кнопку “Установить” на первом элементе, чтобы добавить возможности подсветки Ruby в VS Code. Подождите, пока плагин будет добавлен в IDE. Затем откройте папку ruby-web-scraper с помощью “Файл“, “Открыть папку…“.  

Нажмите на файл scraper.rb под панелью “EXPLORER“, чтобы начать редактирование файла:  

scraper.rb file EXPLORER

Шаг 2: Выберите библиотеку для веб-скрапинга

 

Создание веб-скрапера на Ruby становится проще с правильной библиотекой. По этой причине вам следует взять на вооружение одну из представленных ранее библиотек. Чтобы понять, какая библиотека Ruby для веб-скрапинга подходит лучше всего для ваших целей, понадобится потратить некоторое время на анализ вашего целевого сайта.

Для этого откройте целевую страницу в браузере, щелкните правой кнопкой мыши по странице и выберите опцию “Inspect“. Это приведет к появлению инструментов разработчика в вашем браузере. В Chrome перейдите на вкладку “Сеть” и изучите раздел “Fetch/XHR“.

и изучите раздел "Fetch/XHR".

Как вы можете заметить на скриншоте выше, здесь всего семь AJAX-запросов. Покопайтесь в каждом вызове XHR и вы заметите, что они не содержат никаких значимых данных. Это означает, что целевая страница не получает содержимое во время рендеринга. Таким образом, возвращаемый сервером HTML-документ уже содержит все данные для показа пользователям.

Это доказывает, что целевая страница не использует JavaScript для получения данных или рендеринга. Другими словами, в этом случае для выполнения веб-скрапинга вам не понадобится библиотека с возможностями безголового браузера. Тем не менее, вы все равно можете воспользоваться Mechanize или Selenium, но они скорее притормозят скорость веб-скрапинга, поскольку будут потреблять ресурсы, необходимые им для запуска своего аналога веб-браузера.

Так что вы должны выбрать простой парсер HTML/XML — такой, как, например, Nokogiri. Установите его с помощью nokogiri:

gem install nokogiri

Затем вы можете импортировать библиотеку, добавив следующую строку в начало вашего файла scraper.rb:

require "nokogiri"

Убедитесь, что ваша Ruby IDE не сообщает об ошибках. Если нет, теперь вы можете приступить к веб-скрапингу при помощи Ruby!

Шаг 3: Используйте HTTParty для получения целевой страницы

 

Чтобы спарсить HTML-документ целевой страницы, сначала необходимо загрузить его с помощью HTTP GET-запроса. Ruby поставляется со встроенным HTTP-клиентом под названием Net::HTTP, но его синтаксис немного громоздкий и не отличается простотой и интуитивной понятностью. Вместо него следует использовать HTTParty, которая является самой популярной библиотекой Ruby для выполнения HTTP-запросов.

Установите его с помощью библиотеки httparty:

gem install httparty

Then, import it in the scraper.rb file:

require "httparty"

Use HTTParty to connect to the target page with:

response = HTTParty.get("https://brightdata.com/")

Метод get() позволяет выполнить GET-запрос к URL, переданному в качестве параметра. Поле response.body будет содержать возвращенный сервером HTML-документ.

Обратите внимание, что HTTP-запрос, выполняемый через get(), может завершиться неудачей. Если это произойдет, HTTParty вызовет исключение и остановит выполнение вашего скрипта с ошибкой. Причин неудачи может быть много, но обычно это происходит потому, что анти-бот технология, используемая целевым сайтом, перехватила и заблокировала ваши автоматические запросы. Самые простые системы защиты от ботов обычно отфильтровывают запросы без корректного HTTP-заголовка User-Agent. Посмотрите нашу статью о User-Agent для веб-скрейпинга.

Как и любой другой HTTP-клиент, HTTParty использует заполняемый User-Agent. Обычно он сильно отличается от агентов, используемых популярными браузерами, что делает его запросы легко засекаемыми анти-ботовыми технологиями. Чтобы избежать блокировки из-за этого, вы можете указать правильный User-Agent в HTTParty следующим образом:

response = HTTParty.get("https://brightdata.com/", {

  headers: { "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"},

})

Запрос, выполняемый через get(), теперь будет восприниматься сервером как исходящий от Google Chrome 112.

Вот что содержит scraper.rb в настоящий момент:  


require "nokogiri"
require "httparty"

# get the target page
response = HTTParty.get("https://brightdata.com/", {
  headers: {
    "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",
  },
})

# scraping logic...

Шаг 4: Парсинг HTML-документа с помощью Nokogiri

 

Чтобы спарсить HTML-документ, связанный с целевой страницей, передайте его содержимое в функцию Nokogiri HTML():

doc = Nokogiri::HTML(response.body)

Теперь вы можете использовать API манипулирования и исследования DOM, предлагаемую через переменную doc. В частности, двумя наиболее важными методами выбора элементов HTML являются:

  • xpath(): Возвращает список узлов HTML, соответствующих запросу XPath
  • css(): Возвращает список узлов HTML, соответствующих селектору CSS, переданному в качестве параметра

Хотя оба подхода работают, запросы CSS обычно являются наиболее простым способом получить то, что вам нужно.

Шаг 5: Определите селекторы CSS для интересующих вас элементов HTML

 

Чтобы понять, как выбрать нужные HTML-элементы на целевой странице, необходимо проанализировать DOM. Зайдите на домашнюю страницу Bright Data в браузере, щелкните правой кнопкой мыши на одной из интересующих вас карточек и выберите “Inspect”:  

Inspect

Уделите немного времени изучению кода в разделе DevTools. Каждая карточка в HTML-разметке представляет собой контейнер из тега

, который содержит:

  1. Тег <figure>, содержит внутри себя HTML-элемент <img>, предназначенный для картинки, и элемент <a>, содержащий URL страницы.  
  2. HTML-элемент <div>, содержащий название отрасли в теге <a>.  

Задача Ruby-скрапера — получить URL изображения, URL страницы и название отрасли из каждой карточки.

Чтобы определить подходящие CSS-селекторы, переключите свое внимание на CSS-классы, назначенные интересующим вас узлам DOM. Вы заметите, что с помощью следующего селектора CSS можно получить все карточки:

.section_cases_row_col_item

Получив карточку, вы можете выбрать узлы, хранящие соответствующие данные, из ее дочерних элементов <figure> и <div>:  

  1. figure img
  2. figure a
  3. .elementor-image-box-content a

Шаг 6: Выполните веб-скрапинг данных со страницы с помощью Nokogiri

 

Теперь вам нужно использовать Nokogiri для получения нужных данных с целевой страницы HTML.

Прежде чем погрузиться в логику веб-скрапинга данных, не забудьте, что вам нужны некоторые структуры данных, в которых будут храниться собранные данные. Для этого вы можете определить класс UseCase, причем всего одной строкой благодаря использованию Struct:

UseCase = Struct.new(:image, :url, :name)

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

Инициализируйте пустой массив UseCase и реализуйте логику веб-скрапинга для его заполнения:  

# initialize the list of objects

# that will store all retrieved data

use_cases = []

# select all use case HTML elements

use_case_cards = doc.css(".section_cases_row_col_item")

# iterate over the HTML cards

use_case_cards.each do |use_case_card|

    # extract the data of interest

    image = use_case_card.at_css("figure img").attribute("data-lazy-src").value

    url = use_case_card.at_css("figure a").attribute("href").value

    name = use_case_card.at_css(".elementor-image-box-content a").text

    # instantiate an UseCase object with the

    # collected data

    use_case = UseCase.new(url, image, name)

    # add the UseCase instance to the array

    # of scraped objects

    use_cases.push(use_case)

end

В приведенном выше фрагменте выбираются все карточки, после чего выполняется их перебор. Затем он извлекает из каждой из них URL изображения, URL страницы отрасли и название с помощью функции at_css(). Это функция Nokogiri, которая возвращает первый элемент, соответствующий запросу CSS, и представляет собой ярлык для:

image = use_case_card.css("figure img").first.attribute("data-lazy-src").value

Наконец, он использует полученные данные для создания нового объекта UseCase и добавляет его в список.

Веб-скрапинг с помощью Ruby и Nokogiri довольно прост. С помощью функции attribute() вы можете выбрать атрибут из текущего HTML-элемента. Затем поле value позволяет получить его значение. Аналогично, поле text напрямую возвращает весь текст, содержащийся в текущем HTML-узле, в виде простой строки.

Теперь вы можете пойти дальше и спарсить данные еще и с посвященных отраслям страниц. Для этого нужно проследовать по находящимся здесь ссылкам и реализовать новую логику веб-скрапинга. Добро пожаловать в мир веб-краулинга и веб-скрапинга!  

Фантастика! Вы только что узнали, как достичь своих целей в веб-скрапинге с помощью Ruby. Однако вам предстоит выучить еще несколько уроков.

Шаг 7: Экспорт извлеченных данных

 

После выполненного функцией each() loop цикла, use_cases будет содержать собранные данные в объектах Ruby. Это не самый лучший формат для предоставления данных другим командам. К счастью, Ruby поставляется со встроенными возможностями преобразования в CSV и JSON. Давайте рассмотрим, как экспортировать полученные данные в CSV- или JSON-формат.  

Для экспорта CSV импортируйте следующую библиотеку:

import "csv"

Ruby Standard API предоставляет полноценный интерфейс для работы с данными и CSV-файлами.

Вы можете воспользоваться этим для экспорта массива use_cases в файл output.csv, как показано ниже:

# populate the CSV output file

CSV.open("output.csv", "wb") do |csv|

  # write the CSV header

  csv << ["url", "image", "name"]

  # transfrom each use case scraped info to a

  # CSV record

  use_cases.each do |use_case|

    csv << use_case

  end

end

Приведенный выше фрагмент создает файл output.csv. Затем он открывает его и инициализирует. После этого выполняются итерации по массиву use_cases и добавляет находящиеся в нем данные, в CSV-файл. При использовании оператора << язык Ruby автоматически преобразует каждый экземпляр use_cases в массив строк, как того требует встроенный класс CSV.

Попробуйте запустить скрипт с:  

ruby scraper.rb

В корневом каталоге вашего проекта будет создан файл output.csv, содержащий приведенные ниже данные:

Файл output.csv, содержащий приведенные ниже данные, будет создан в корневом каталоге вашего

Аналогично, вы можете экспортировать use_cases в файл output.json:  

# propulate the JSON output file

File.open("output.json", "wb") do |json|

  json << JSON.pretty_generate(use_cases.map { |u| Hash[u.each_pair.to_a] })

end

В результате будет сгенерирован следующий JSON-файл:  

[

  {

    "image": "https://brightdata.com/use-cases/ecommerce",

    "url": "https://brightdata.com/wp-content/uploads/2022/07/E_commerce.svg",

    "name": "eCommerce "

  },

  // ...

  {

    "image": "https://brightdata.com/use-cases/data-for-good",

    "url": "https://brightdata.com/wp-content/uploads/2022/07/Data_for_Good_N.svg",

    "name": "Data for Good"

  }

]

И вуаля! Теперь вы знаете, как в Ruby преобразовать массив структур в CSV- или JSON-формат!

Шаг 8: Собираем все вместе

 

Вот полный код веб-скрапера Ruby:

# scraper.rb

require "nokogiri"

require "httparty"

require "csv"

# get the target page

response = HTTParty.get("https://brightdata.com/", {

  headers: {

    "User-Agent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36",

  },

})

# parse the HTML document retrieved with the GET request

doc = Nokogiri::HTML(response.body)

# define a class where to keep the scraped data

UseCase = Struct.new(:image, :url, :name)

# initialize the list of objects

# that will store all retrieved data

use_cases = []

# select all use case HTML elements

use_case_cards = doc.css(".section_cases_row_col_item")

# iterate over the HTML cards

use_case_cards.each do |use_case_card|

  # extract the data of interest

  image = use_case_card.at_css("figure img").attribute("data-lazy-src").value

  url = use_case_card.at_css("figure a").attribute("href").value

  name = use_case_card.at_css(".elementor-image-box-content a").text

  # instantiate an UseCase object with the

  # collected data

  use_case = UseCase.new(url, image, name)

  # add the UseCase instance to the array

  # of scraped objects

  use_cases.push(use_case)

end

# populate the CSV output file

CSV.open("output.csv", "wb") do |csv|

  # write the CSV header

  csv << ["url", "image", "name"]

  # transfrom each use case scraped info to a

  # CSV record

  use_cases.each do |use_case|

    csv << use_case

  end

end

# propulate the JSON output file

File.open("output.json", "wb") do |json|

  json << JSON.pretty_generate(use_cases.map { |u| Hash[u.each_pair.to_a] })

end

Всего 50 строчек кода на языке Ruby — и в вашем распоряжении полноценный скрипт для парсинга данных из интернета!

Заключение

Из этого руководства вы узнали, почему Ruby — отличный язык для веб-скрапинга в интернете. Вам также представилась возможность увидеть, какие библиотеки Ruby наиболее оптимальны для парсинга и какие возможности они предлагают. Также вы узнали, как использовать Nokogiri и стандартный API Ruby для создания веб-скрапера, который способен парсить реальные сайты. Как мы наглядно продемонстрировали, в действительности код Ruby, позволяющий реализовать эффективный веб-скрапинг данных, будет состоять из минимального количества строк.

Однако не стоит недооценивать стоящие перед скраперами проблемы, когда речь идет об извлечении данных из реальных интернет-страниц. Например, все большее количество сайтов внедряет умные системы защиты от скрапинг-ботов для защиты собственных данных. Эти технологии способны обнаружить запросы, выполняемые вашим скриптом Ruby для выполнения веб-скрапинга, и запретить ему доступ к сайту. К счастью, вполне реально создать веб-скрапер, который способен обойти любые блокировки. Для этого вам понадобится Web Scraper IDE нового поколения от Bright Data.

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