フリーダムの日記

GIS(地理情報システム)を中心に技術的なことを書いています。

Rails スクレイピング手法 Mechanize について

はじめに

今回久しぶりの Rails の開発で ruby の Mechanize という gem を使用してみて、とても便利でしたので、簡単ではありますが紹介したいと思います。他に nokogiri というスクレイピングするライブラリーもあります。

f:id:freedom0625:20200808004132j:plain

Mechanize とは

Mechanize は、Web サイトなどの Web をスクレイピングしてくれる便利な ruby のライブラリです。ruby 以外にも Python でも提供しているそうです。

github.com

Google News RSS の利用

今回は、Google News RSS を利用して Mechanize を利用した例をご紹介したいと思います。Google News RSS から例えば、AI や IoT などのキーワードで検索して、該当のページのURLやタイトル、詳細情報などを取得して、クライアント端末などに情報を表示します。ただし、画像などの情報を表示したい場合は、該当の URL からページをスクレイピングして OGP で画像情報も取得することができます。

OGPとは uideal.net

こちらの Google ニュースRSS ジェネレータでは、キーワードを入力することで、検索して、RSS を生成します。タグなどの必要な項目を確認することができます。

g.1o4.jp

Mechanize のインストール

まずは mechanize という gem をインストールします。
Rails の Gemfile に以下を記述します。

gem  'mechanize'

その後、bundle install でインストールを行います。
bundle install --path vendor/bundle

これで mechanize を使用する準備が整いました。

Mechanize の利用方法

まず、Mechanizeクラスのインスタンスを生成し、get メソッドを用いてスクレイピングする Web サイトの HTML 情報を取得します。

# Mechanize クラスのインスタンスを生成
agent = Mechanize.new
agent.follow_meta_refresh = true
    
base_url = 'https://news.google.com/rss/search'
query_string = "?hl=ja&q=#{keyword}&hl=ja&gl=JP&ceid=JP:ja"

#  get メソッドを用いてスクレイピングするウェブサイトの HTML 情報を取得
page = agent.get(base_url + query_string)

例えば、AI をキーワードで検索した場合に 以下のように item タグに情報がリストとなって取得されます。

<item>
   <title>AIで実写映像やアニメを高画質化 超解像処理とノイズリダクションを施す - Ledge.ai</title>
   <link>https://ledge.ai/radius5/</link> 
   <guid isPermaLink="false">CBMiGWh0dHBzOi8vbGVkZ2UuYWkvcmFkaXVzNS_SAQA</guid>
   <pubDate>Fri, 07 Aug 2020 08:00:47 GMT</pubDate>
   <description><a href="https://ledge.ai/radius5/" target="_blank">AIで実写映像やアニメを高画質化 超解像処理とノイズリダクションを施す 
   </a>&nbsp;&nbsp;<font color="#6f6f6f">Ledge.ai</font></description>
   <source url="https://ledge.ai">Ledge.ai</source>
</item>

そして、その Web サイトから任意の情報を検索して取得する場合は、search メソッドを使用します。 例えば、タイトルのリストなどを取得したい場合は、search メソッドに title を指定します。title のリストを取得することができます。また、item を指定することで item タグのリストを取得することができます。

titles = page.search("//title")
items = page.search("//item")

at メソッドを使用することで、1件だけ取得することができます。

titles = page.at("//title")
items = page.at("//item")

item タグのリストを取得したい場合は、以下のような例になります。
実際に文字列の抽出は、text を指定することで取得できます。

items = page.search("//item")
 
items.each do |item|

   title = item.at("title/text()").text
   pubDate = item.at("pubDate/text()").text
   description = item.at("description/text()").text
   link = item.at("link/text()").text
 
end

また、上記の link から OGP を取得する場合は、以下のように meta タグを指定することで簡単に取得することができます。

page = agent.get(link) 
ogp = page.at("meta[property='og:image']")[:content]

さいごに

久しぶりに Rails で 新しい gem の Mechanize をインストールして使用してみました。とても便利なライブラリで簡単にスクレイピングして目的の情報を取得することができました。ただし、検索には時間がかかる場合があるので、クラインアント側で検索して使用する場合には、ページングなどで件数の制限やキャッシュ機能などパフォーマンスの工夫は必要になってくると思います。

その他、以下のサイトにさせていただきました。 www.xmisao.com www.xmisao.com