Как разбирать результаты Google Local Pack
Table Of Content
Парсинг результатов Google Local Pack - это не простая задача. Однако эти локальные результаты становятся все более и более распространенными.
Вот пример верхнего результата запроса "кофе" в Остине, Техас:
В этом руководстве я расскажу о том, как мы создаем такой парсер в SerpApi, API результатов поиска Google.
Если вы хотите запустить код самостоятельно, вам понадобятся:
Ruby (>= 2.1)
Rails (>= 5.1) # Не обязательно, но некоторые его методы удобны
Nokogiri gem
Сначала нам нужно определить, что нужно извлечь. Также важно дать каждому из этих элементов описательное имя, чтобы в будущем было легче ссылаться на них.
Вот макет того, что наш парсер должен извлечь:
Во-вторых, нам нужно определить глобальный селектор для этого блока. Инструмент Chrome Inspector очень удобен:
CSS-класс на div xERobd
кажется хорошим селектором для полного локального пакета. Вот результирующий код на Ruby, который мы будем использовать:
def get_local_results
# Разбор HTML с помощью Nokogiri
doc = Nokogiri::HTML(html) # Убедитесь, что у нас есть блок с локальными результатами
local_results_top = doc.at_css('.xERobd')
return unless local_results_top
end
Теперь давайте извлечем наши первые данные. Изображение Google Maps и другую информацию о местоположении. Мы находим селекторы CSS-классов таким же образом:
Интересно, что мы замечаем внутри ссылки Google Maps некоторые данные, похожие на GPS. Структурировано это так: rllag=30265614,-97744454,182
. Это похоже на обычные GPS-координаты. Долгота, широта и высота. После проверки, что это действительно GPS-координаты, соответствующие нашему запросу через сторонний сервис, такой как gps-coordinates.net, мы решаем включить эти данные в наш парсер. Нам нужно регулярное выражение, чтобы выбрать часть ссылки Google Maps, которую мы хотим, некоторую утилиту для очистки текста, чтобы вернуться к более обычному формату GPS-координат, и структурировать его для нашего JSON-вывода. Конечный код выглядит так:
def extract_gps_coordinates(google_maps_link)
coords_raw = google_maps_link.scan(/rllag=([0-9\-,]+)&/)[0][0].split(',')
coords = {}
coords[:latitude] = coords_raw[0].insert(-7, '.').to_f
coords[:longitude] = coords_raw[1].insert(-7, '.').to_f
coords[:altitude] = coords_raw[2].to_i
coords
end
Мы используем те же техники для поиска CSS-селекторов для заголовка места, типа бизнеса (кофейня, ресторан, супермаркет и т. д.), его цены, его часов работы, его отрывка (небольшое описание сразу после заголовка), его рейтинга, его отзывов, его адреса, его миниатюры и расширений места (список ключевых слов, описывающих особенности места).
Конечный код, проходящий через результаты мест, выглядит так:
local_results = []
local_results_top.css('.uMdZh').each_with_index do |local_result, index|
local_result_hash = Hash.new{ |h,k| h[k] = Hash.new(&h.default_proc) }
local_result_hash[:position] = index + 1
local_result_hash[:title] = local_result.at_css('._rl').text
local_result_hash[:address] = local_result.css('.rllt__details > div')[2].text
local_result_hash[:hours] = local_result.at_css('.rllt__details > .rllt__wrapped').text
local_keywords = []
local_result.css('.UGaK9c').each do |keyword|
local_keywords << keyword.text.gsub('·','').squish
end
unless local_keywords.empty?
local_result_hash[:extensions] = local_keywords
end
if img = local_result.at_css('img')['src'] rescue nil
local_result_hash[:thumbnail] = img
end
local_results << local_result_hash
end
Этот код нужно обновлять каждые 2-3 недели, так как Google постоянно меняет способ отображения результатов. Вы можете следить за изменениями, пройдя через описанный процесс, или вы можете использовать наш сервис SerpApi, который абстрагирует все это и многое другое для вас.