CoderCastrov logo
CoderCastrov
Парсер

Парсинг веб-страниц с использованием Nokogiri

Парсинг веб-страниц с использованием Nokogiri
просмотров
5 мин чтение
#Парсер

Как говорят, "Парси то, что тебе дала мама"

Что такое парсинг веб-страниц?

Очень часто при создании приложений нам нужны данные. Данные обычно поступают в виде API (Application Program Interfaces), которые мы находим или разрабатываем сами. Эти API улучшают наши приложения, предоставляя большую часть контента, на котором работают наши страницы, и могут быть настолько обширными, что поиск API, подходящего для ваших нужд, может показаться выигрышем в лотерею.

Однако часто мы оказываемся в ситуации, когда нам нужны данные, которые настолько узкоспециализированы или специфичны, что для них не существует подходящего API. Решение - парсинг веб-страниц. Парсинг веб-страниц - это то, как звучит, "скрэпинг" (скрэпинг) веб-страниц (или, более точно, HTML конкретных страниц) с помощью мелкозубой гребенки, чтобы получить информацию, которую мы хотим использовать сами, не копируя ее дословно.

Например, предположим, вы большой фанат тенниса и создаете приложение, которое позволяет пользователям отслеживать своих любимых игроков Женской теннисной ассоциации (WTA) и их текущие рейтинги, возможно, получая уведомления о их матчах и рейтинговых очках. У нас уже есть проблема. Существует так много игроков WTA, и в любой момент может появиться новые игроки, уходят в отставку, и рейтинги меняются ежедневно. Можно сказать, что маловероятно, что для этого будет API.

Если мы перейдем по адресу https://www.wtatennis.com/rankings/singles, мы увидим список всех игроков и их текущий рейтинг и очки. Это данные, которые мы хотим получить, и мы можем получить их с помощью парсинга. В консоли инструментов разработчика (я использую, конечно, Chrome) вы можете увидеть HTML-код сайта, и когда вы наводите указатель мыши на отдельных игроков, вы можете увидеть точное место в HTML-коде, где находится этот текст, как показано ниже.

Как видите, наша мышь наведена на Ашли Барти и подсвечивается в элементах инструмента. (Мы тебя любим, Аш, поздравляю с уходом на пенсию в 25 лет, это моя мечта). Итак, мы можем найти и выбрать этот <td> для каждого игрока, пройтись по ним и добавить их в нашу базу данных!

Вот пошаговая инструкция, что мы сделаем.

require 'nokogiri'
require 'open-uri'
require 'pry'
  1. Получите URL, который вы хотите использовать, и используйте метод open из 'open-uri', чтобы установить его в переменную.
html = URI.open("[http://www.tennisnow.com/Rankings/WTA-Singles.aspx](http://www.tennisnow.com/Rankings/WTA-Singles.aspx)")
  1. Получите доступ к HTML с помощью Nokogiri и только что созданной переменной html, и установите его в переменную.
doc = Nokogiri::HTML(html)

4a. (Дополнительный рефакторинг) Объедините две предыдущие строки кода.

doc = Nokogiri::HTML(URI.open("[http://www.tennisnow.com/Rankings/WTA-Singles.aspx](http://www.tennisnow.com/Rankings/WTA-Singles.aspx)"))
  1. Используйте binding.pry, чтобы выбрать нужную вам информацию. Вот что у вас должно получиться на данный момент.
**require** 'nokogiri'
**require** 'open-uri'
**require** 'pry'_def_ create_playerinfo **=** Nokogiri::HTML(URI.open("http://www.tennisnow.com/                        Rankings/WTA-Singles.aspx"))binding.pry_end_create_player //вызов функции для входа в сеанс pry

В вашем сеансе pry используйте метод .css для переменной info, чтобы попробовать выбрать нужные элементы. Вы можете выбирать практически все в HTML. Используйте '#' для идентификаторов, "." для классов и обычные кавычки для тегов элементов (например, .css('.thisIsAClass') или .css('#thisIsAnID') или .css('h1')).

Таким образом, мы можем видеть, что имена являются частью таблицы (этот веб-сайт действительно состоит из множества div-элементов, ужас, но, эй, что было бы с парсингом без драмы). В любом случае, кажется, что это хорошее место для начала! Если мы попробуем это, мы должны получить огромный ответ.

pry(main)> info.css('table')

Это выглядит дико, но именно то, что нам нужно! Следующий шаг - найти эти имена.

  1. Давайте попробуем добавить еще один .css, чтобы выбрать каждое имя.
pry(main)> info.css('table').css('td span')

Это даст нам все спаны для каждой строки. Если мы добавим .text, мы должны получить некоторые данные, которые нам знакомы.

pry(main)> info.css('table').css('td span').text

Как видите, у нас есть каждый td span. Поскольку у каждого игрока есть 3 td span, мы получаем их рейтинг, имя и текущие очки. (Кстати, вау, как Ашли изменилась с момента, когда я начал писать этот блог до того, как я его закончил).

Если мы хотим получить только их имя, нам придется немного поработать, чтобы просеять данные. Вот что я сделал.

_def_ create_player
  info **=** Nokogiri::HTML(URI.open("http://www.tennisnow.com/                           Rankings/WTA-Singles.aspx"))  info.css('table').css('td span').each **do** |player|
    _if_ **!**player.text.strip.scan(/\D/).empty?
     puts player.text.strip
    _end  endend_

По сути, поскольку этот веб-сайт состоял из множества div-элементов и мне было трудно выбрать то, что я хотел, я перебрал все <td>``<spans> и сказал, что если в них нет цифр, выводить их в терминал. Я признаю, что это не красивое решение и надеюсь, что вы найдете что-то лучшее. Но в мире парсинга, если это работает, то это работает.

Дальнейшие шаги

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

Player.create(name: player.text.strip)

И вуаля, за считанные секунды вы добавили всех этих игроков в свою базу данных.

Заключение

Хотя этот блог только касается поверхности парсинга (прошу прощения за эту шутку), важно понимать, что парсинг может быть борьбой, но это стоит того в конце концов. Парсинг можно использовать для экономии часов и даже дней времени, так что попробуйте на своем любимом веб-сайте и посмотрите. Нам есть, за что благодарить гем Nokogiri.

TL:DR;

require 'nokogiri'
require 'open-uri'
require 'pry'
  1. Получите HTML с веб-сайта, который вы выбрали
doc = Nokogiri::HTML(URI.open("ВСТАВЬТЕСЮДАВАШURL"))
  1. Войдите в сеанс pry и используйте метод .css, чтобы найти нужные элементы

  2. Используйте эти элементы для заполнения вашей базы данных. Это так просто!

  3. Как только вы добьетесь успеха, похвалите себя. Ашли гордится.