Этот руководство научит вас правильно извлекать данные с сайта с использованием Ruby и объяснит, почему это один из самых эффективных языков программирования для веб-скрапинга.
В данном руководстве будут рассмотрены:
- Подходит ли Ruby для веб-скрапинга?
- Лучшие библиотеки для веб-скрапинга на языке 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 часто меняется и к тому моменту, когда вы будете читать эту статью, она может уже слегка видоизмениться.
Конкретная цель веб-скрапинга — получить информацию, содержащуюся в следующих карточках:
Следуйте приведенному ниже пошаговому руководству и узнайте, как выполнять веб-скрапинг с помощью 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“, чтобы начать редактирование файла:
Шаг 2: Выберите библиотеку для веб-скрапинга
Создание веб-скрапера на Ruby становится проще с правильной библиотекой. По этой причине вам следует взять на вооружение одну из представленных ранее библиотек. Чтобы понять, какая библиотека Ruby для веб-скрапинга подходит лучше всего для ваших целей, понадобится потратить некоторое время на анализ вашего целевого сайта.
Для этого откройте целевую страницу в браузере, щелкните правой кнопкой мыши по странице и выберите опцию “Inspect“. Это приведет к появлению инструментов разработчика в вашем браузере. В Chrome перейдите на вкладку “Сеть” и изучите раздел “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”:
Уделите немного времени изучению кода в разделе DevTools. Каждая карточка в HTML-разметке представляет собой контейнер из тега, который содержит:
- Тег <figure>, содержит внутри себя HTML-элемент <img>, предназначенный для картинки, и элемент <a>, содержащий URL страницы.
- HTML-элемент <div>, содержащий название отрасли в теге <a>.
Задача Ruby-скрапера — получить URL изображения, URL страницы и название отрасли из каждой карточки.
Чтобы определить подходящие CSS-селекторы, переключите свое внимание на CSS-классы, назначенные интересующим вас узлам DOM. Вы заметите, что с помощью следующего селектора CSS можно получить все карточки:
.section_cases_row_col_item
Получив карточку, вы можете выбрать узлы, хранящие соответствующие данные, из ее дочерних элементов <figure> и <div>:
- figure img
- figure a
- .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, содержащий приведенные ниже данные:
Аналогично, вы можете экспортировать 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.
Кредитная карта не требуется
Не хотите заниматься веб-скрапингом, но интересуетесь разнообразными интернет-данными? Изучите наши готовые к использованию наборы данных.