Рубрики
Без рубрики

Как соскребать рубиновые и нокогири и отображать данные

Andrew Taxes Как соскребаться с Ruby и Nokogiri и на карте DataRuby, JSON и Nobogirisometimes, вы хотите получить данные с сайта для своего собственного проекта. Так что вы используете? Ruby, Nokogiri и Json к спасению! Недавно я работал над проектом на карту

Автор оригинала: FreeCodeCamp Community Member.

Andrew Tales

Иногда вы хотите получить данные с сайта для вашего собственного проекта. Так что вы используете? Ruby, Nokogiri и Json к спасению!

Недавно я работал над проектом на карту Данные о мостах Отказ Используя Nokogiri, я смог захватить данные моста города из таблицы. Затем я использовал ссылки в той же таблице, чтобы скрепить связанные страницы. Наконец, я преобразовал SCRAPED DATA в JSON и использовал его для заполнения карты Google.

Эта статья проходит вас через инструменты, которые я использовал и как работает код!

Смотрите полный код на моем Github репо.

Живая карта Demo здесь Отказ

Проект

Моя цель состояла в том, чтобы взять стол из данных моста Сайт И включите его на карту Google с геологическими контактами, которые создали бы информационные всплывающие окна для каждого моста.

Чтобы это случилось, мне нужно:

  1. Scrape Data с оригинального сайта.
  2. Преобразуйте эти данные в JSON Object Отказ
  3. Примените эти данные, чтобы сделать новую интерактивную карту.

Ваш проект будет варьироваться, наверняка – сколько людей пытаются набрать антикварные мосты? – Но я надеюсь, что этот процесс окажется полезным для вашего контекста.

Nokogiri

Ruby имеет удивительный веб-канализационный драгоценный камень Nokogiri Отказ Среди других функций он позволяет искать HTML-документы CSS селекторами. Это означает, что если мы знаем IDS, классы или даже типы элементов, где данные хранятся в DOM, мы можем вырвать это.

Скребок

Если вы следуете наряду с Gibhub Repo , вы можете найти мой скребок в bridges_scraper.rb

require 'open-uri'require 'nokogiri'require 'json'

Open-Uri позволяет нам открывать HTML как файл и передавать его на нокогири для тяжелой подъема.

В приведенном ниже коде я передаю информацию DOM с URL-адреса с мостом данных на Nokogiri. Затем я нахожу элемент таблицы, удерживающую данные, ищите его строки и итерацию через них.

url = 'https://bridgereports.com/city/wichita-kansas/'html = open(url)
doc = Nokogiri::HTML(html)bridges = []table = doc.at('table')
table.search('tr').each do |tr|  bridges.push(    carries: cells[1].text,    crosses: cells[2].text,    location: cells[3].text,    design: cells[4].text,    status: cells[5].text,    year_build: cells[6].text.to_i,    year_recon: cells[7].text,    span_length: cells[8].text.to_f,    total_length: cells[9].text.to_f,    condition: cells[10].text,    suff_rating: cells[11].text.to_f,    id: cells[12].text.to_i  )end
json = JSON.pretty_generate(bridges)File.open("data.json", 'w') { |file| file.write(json) }

Nokogiri имеет много методов (вот есть Cheat Sheet и стартер Руководство !). Мы используем всего несколько.

Таблица найдена с .at («Таблица») , который возвращает первый вхождение элемента таблицы в доме. Это работает просто для этой относительно простой страницы.

Со столом в руке, .Search («TR») Предоставляет массив элементов строки, которые мы повторяемся с .each Отказ В каждом ряду данные очищаются и выдвинуты в одну запись для массива мостов.

После того, как все строки собраны, данные преобразуются в JSON и сохраняются в новом файле под названием «Data.json».

Сочетание данных с нескольких страниц

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

Мне нужно было написать код, который сделал несколько вещей:

  • Собранные ссылки от первой ячейки в таблице.
  • Создан новый объект Nokogiri из HTML на этой странице.
  • Вытащить широту и долготу.
  • Спи программу, пока этот процесс не завершится.
cells = tr.search('th, td')  links = {}  cells[0].css('a').each do |a|    links[a.text] = a['href']  end    got_coords = false    if links['NBI report']    nbi = links['NBI report']    report = "https://bridgereports.com" + nbi    report_html = open(report)    sleep 1 until report_html    r = Nokogiri::HTML(report_html)        lat = r.css('span.latitude').text.strip.to_f    long = r.css('span.longitude').text.strip.to_f
    got_coords = true  else    got_coords = true  end    sleep 1 until got_coords == true
  bridges.push(        links: links,        latitude: lat,        longitude: long,        carries: cells[1].text,        ..., # all other previous key/value pairs  )end

Несколько дополнительных вещей стоит указывать здесь:

  • Я использую «got_coords» как простым двоичным. Это установлено на ложь По умолчанию и переключается, когда данные захвачены или просто недоступны.
  • Широта и долгота расположены в промежутках с соответствующими классами. Это делает защищать данные простым: .css (‘Spanip.latitude’) Следуют .Text, .Strip и .to_f Какой 1) получает текст с пролета, 2) полос любых избыточных пробелов, а 3) преобразует строку в номер поплавка.

JSON → Google Map

Недавно сформированный объект JSON должен быть изменен прикосновение, чтобы соответствовать API Google Maps. Я сделал это с JavaScript внутри map.js.

Данные JSON доступны внутри map.js Поскольку он был перемещен в папку JS, назначенную переменной под названием «Brance_data» и включен в тег