Один (простой) способ парсинга веб-сайта с помощью Rails
Я знаю, что сейчас 2019 год, но все еще есть веб-сайты, которые не предоставляют API.
Иногда вам может понадобиться спарсить данные с другого веб-сайта и отобразить их в вашем приложении Rails. Вот учебник о том, как это сделать.
Сначала вам нужно создать свое приложение. Напишите в терминале следующую команду:
rails new app
Затем выполните
bundle install
После этого вам нужно сгенерировать контроллер и представления:
rails generate static_pages index
После выполнения этой команды автоматически будут сгенерированы контроллер и представления для статических страниц.
Вот контроллер:
Предупреждение: Я использую VIM и люблю его.
Вот представление:
После этого нам нужно изменить маршруты, чтобы мы могли увидеть нашу таблицу, и я обещаю, что после этого мы начнем делать что-то полезное. Но сначала напишите в файле маршрутов:
root ‘static_pages#index’
Приступаем к работе
Вероятно, вы уже знаете свою цель, но для этой статьи я буду использовать таблицу из португальской футбольной лиги с веб-сайта zerozero.pt.
Сначала нам нужно установить гем nokogiri (если вы не хотите читать, просто добавьте "gem 'nokogiri'" в ваш файл gem) и запустите команду:
bundle install
После этого мы готовы начать парсить.
Добавьте в ваш помощник static_pages следующий код:
pagetovisit = 'https://www.zerozero.pt/edicao.php?id_edicao=135717'
content = open(pagetovisit).read
html_doc = Nokogiri::HTML(content)
print html_doc
Если вы запустите этот код и проверите ваш терминал, вы увидите весь HTML-код нашей целевой страницы.
Но вы хотите выбрать только таблицу с рейтингами. Что же нужно сделать?
Вам нужно найти уникальный идентификатор. Если вы проверите изображение, вы легко увидите, что в этом случае я буду использовать класс "zztable", но вы можете использовать идентификатор или что-то другое, просто используйте инструменты разработчика.
Ваш помощник должен выглядеть следующим образом:
pagetovisit = 'https://www.zerozero.pt/edicao.php?id_edicao=135717'
content = open(pagetovisit).read
html_doc = Nokogiri::HTML(content)
table = html_doc.css('table.zztable')
data = []
print table
Теперь вы видите, что у нас есть весь HTML-код таблицы. Теперь мы начнем сохранять всю нужную информацию.
Теперь мы получаем строки, мы знаем, что строки представлены тегом <tr>
, поэтому это становится просто.
rows = table.css('tr')
Ваш помощник теперь выглядит следующим образом:
pagetovisit = 'https://www.zerozero.pt/edicao.php?id_edicao=135717'
content = open(pagetovisit).read
html_doc = Nokogiri::HTML(content)
table = html_doc.css('table.zztable')
data = []
rows = table.css('tr')
После этого, если мы хотим, мы можем сохранить строки в массиве для отображения позже. Предположим, что мы хотим сохранить название команды, количество выигранных игр, количество проигранных игр и общее количество очков, мы хотим сохранить строки 3, 6, 8 и 4.
rows.map do |row|
data.push([row.at_css('td:nth-child(3)').try(:text), row.at_css('td:nth-child(6)').try(:text), row.at_css('td:nth-child(8)').try(:text), row.at_css('td:nth-child(4)').try(:text)])
end
Я использую метод try(:text), потому что если что-то равно nil и не является текстом, это не вызовет ошибку, и поскольку я верну массив.compact, это не имеет значения для этого примера.
Ваш полный помощник теперь выглядит следующим образом. Обратите внимание на заголовки внизу, потому что мы будем использовать их в представлении.
pagetovisit = 'https://www.zerozero.pt/edicao.php?id_edicao=135717'
content = open(pagetovisit).read
html_doc = Nokogiri::HTML(content)
table = html_doc.css('table.zztable')
data = []
rows = table.css('tr')
Передача собранных данных в представление
Просто делайте то, что хотите с кодом. Я создал простую таблицу, вы можете свободно стилизовать ее.
Итоговый результат
Вот как все выглядит. Если вы пытаетесь спарсить веб-сайт с динамически генерируемым контентом с помощью JS, это немного сложнее, но в конце концов все идет по тому же пути.
Удачи в парсинге веб-сайтов.