0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ItayaAdvent Calendar 2022

Day 2

久々にRubyでスクレイピングをしてみよう

Posted at

概要

一時期呼吸するようにスクレイピングをしていたのですが、最近しておらず職場で少々それ関係の話題になったのであらためてここに簡単なものを残しておこうと思う。

環境

ruby 3.1.2

準備

rubyなのでGemfileを定義します。

Gemfile

source 'https://rubygems.org'

gem 'nokogiri'

HTMLのパースのためにnokogiriを使うのでこれだけ用意します。
ほかは標準で入っているものでjsonのパースとかしてくれる(強い)

作業ディレクトリで下記のコマンドを実行

bundle install --path .bundle

ただのbundle installだとグローバルに入っちゃったりするので、パス指定しておくほうがおすすめです。

実装

では、結論から

require 'net/http'
require 'uri'
require 'nokogiri'
require 'kconv'
require 'json'
require 'pp'

uri = URI.parse("https://tabelog.com/kanagawa/A1401/A140101/14011244/")
request = Net::HTTP::Get.new(uri)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

doc = Nokogiri::HTML.parse(response.body.toutf8, nil, 'utf-8')
p '###ページタイトル取得###'
p doc.title

json = JSON.parse(doc.css('script[type="application/ld+json"]')[0])
p '###お店の名前を取得###'
p json['name']

p '###画像の一覧を取得###'
doc.css('.js-mainphoto-slider img').map do |img|
  p img['src']
end

これで食べログのある飲食店の店の名前と使われている画像の一覧(URL)を取得できます。
結果

###ページタイトル取得###
おでんと庭先地鶏 はれ晴れ 横浜店 (はればれ) - 横浜/居酒屋/ネット予約可 | 食べログ

###お店の名前を取得###
おでんと庭先地鶏 はれ晴れ 横浜店

###画像の一覧を取得###
https://tblg.k-img.com/resize/660x370c/restaurant/images/Rvw/132571/132571144.jpg?token=20cb762&api=v2
https://tblg.k-img.com/resize/660x370c/restaurant/images/Rvw/24900/24900734.jpg?token=b9868a4&api=v2
https://tblg.k-img.com/resize/660x370c/restaurant/images/Rvw/56132/56132013.jpg?token=fe9448b&api=v2
https://tblg.k-img.com/resize/660x370c/restaurant/images/Rvw/78170/78170969.jpg?token=3fd4c48&api=v2
https://tblg.k-img.com/resize/660x370c/restaurant/images/Rvw/56132/56132018.jpg?token=b87b67e&api=v2
https://tblg.k-img.com/resize/660x370c/restaurant/images/Rvw/164984/a21f498d57e0457c36be973f135bac48.jpg?token=d673ae7&api=v2
https://tblg.k-img.com/resize/660x370c/restaurant/images/Rvw/180013/db2d95a874b50da3583495e37adadb02.jpg?token=c6f6e88&api=v2
https://tblg.k-img.com/resize/660x370c/restaurant/images/Rvw/183264/b46e2b28ba4a9198d62b3bae77ce86f7.jpg?token=3291219&api=v2
https://tblg.k-img.com/resize/660x370c/restaurant/images/Rvw/183264/f1706f12f7eaf63b6103aa6ef52db217.jpg?token=13b84c0&api=v2
https://tblg.k-img.com/resize/660x370c/restaurant/images/Rvw/183334/7a5fd20ba0cc51c95fae81fece7c9475.jpg?token=13ebd97&api=v2

解説

軽くコードの解説します。

1. ページ情報の取得

まず、何はともあれページの情報をとってくる必要があります。
リクエスト用のGemなどもありますが、標準で入っているnet/httpがただのリクエスト飛ばすのにはわかりやすいのでこちらを利用。
URLを指定し、Getのリクエストでページの情報を取得してます。

uri = URI.parse("https://tabelog.com/kanagawa/A1401/A140101/14011244/")
request = Net::HTTP::Get.new(uri)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

2. 取得したHTMLを解析

上記で取得したページ情報からbody情報を使います。
また、その際に.toutf8してましてこれをしておくとshift-jisとかのものもutf-8にしてくれてその後の処理で文字化けてるとか言う悲しい気持ちにならないで済みます。

doc = Nokogiri::HTML.parse(response.body.toutf8, nil, 'utf-8')

3. 情報の取得

もうここからはなんの情報がほしいかっていうここの要件に関わる部分になります。
パターンがおおいほうが幸せな人もおおいかなと思っていくつか書いてます。

p '###ページタイトル取得###'
p doc.title

json = JSON.parse(doc.css('script[type="application/ld+json"]')[0])
p '###お店の名前を取得###'
p json['name']

p '###画像の一覧を取得###'
doc.css('.js-mainphoto-slider img').map do |img|
  p img['src']
end

1個目はnokogiriの方の機能でページのタイトルをとってくるものになってます。
2個目はページの中に埋め込まれているjson情報をパースしてそこから情報を取得しています。
3個目はhtmlの中から特定の要素をセレクタ指定してとってきています。

大体この3パターンを抑えておけばあとは自力で情報までたどりつけるかと.....

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?