[Rails4でサイト構築をする]
- Rails環境構築編
- Scaffold利用編
- Bootstrap導入編
- WYSIWYG導入編
- CSV出力機能編
- スクレイピング機能編(nokogiri)
- 非同期処理導入編(delayed_job)
- デプロイ環境構築編(capistrano3)
上記を毎週1つずつ出す予定
今回は別のサイトのHTMLをパースして情報を取得する機能を作ってみたいと思います。
HTMLのパースにはNokogiriというプラグインを使います。
Nokogiriのインストール
Gemfileに以下を追加する
gem 'nokogiri'
そして、bundle install
Nokogiriを使って別サイトのHTMLから情報を取得する
対象サイトのHTMLを把握する
試しに、弊社のサイト(//www.bpsinc.jp)のグローバルナビの情報を取得してみたいと思います。
画像の赤枠部分。
画像の赤枠部分のHTML
<div class="container clearfix">
<ul id="primary" class="nav">
<li id="menu-item-7768" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-7768"><a href="https://www.bpsinc.jp/">Home</a></li>
<li id="menu-item-7532" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-7532"><a href="https://www.bpsinc.jp/company">会社概要</a></li>
<li id="menu-item-7733" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-7733"><a href="https://www.bpsinc.jp/rails">Ruby on Rails</a></li>
<li id="menu-item-7736" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-7736"><a href="https://www.bpsinc.jp/epub">EPUB電子書籍</a></li>
<li id="menu-item-11426" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-11426"><a href="https://www.bpsinc.jp/manga_translation">漫画翻訳</a></li>
<li id="menu-item-7730" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-7730"><a href="https://www.bpsinc.jp/manga-reborn">MANGAREBORN</a></li>
<li id="menu-item-10493" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-10493"><a href="https://www.bpsinc.jp/seo-lpo-efo-listing-analytics">SEO対策</a></li>
<li id="menu-item-9336" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-9336"><a target="_blank" href="https://techracho.bpsinc.jp/">開発ブログ</a></li>
<li id="menu-item-7735" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-7735"><a href="https://www.bpsinc.jp/recruit">採用</a></li>
<li id="menu-item-7734" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-7734"><a href="https://www.bpsinc.jp/contact">お問い合わせ</a></li>
</ul>
</div> <!-- end .container -->
</div> <!-- end #menu -->
目的とするグローバルナビの要素(会社概要とか、漫画翻訳など)のCSSを特定するにはどうすればよいかを考えてみます。
liタグにidがついており、idはすべて"menu-item-任意の数字"となっています。そしてそのあとにaタグといった構造になっています。
なので、'li[id*="menu-item-"] a'としてあげればよさそうです。
HTMLをパースする機能を持つモジュールの作成
モジュールを作らなければできないなんてことはないですが、モジュールとしてまとめて使いまわせるようにしておくと何かと便利です。
モジュールの作成
lib/scrape.rb
require 'open-uri'
module Scrape
BPS_SITE_URL = '//www.bpsinc.jp'
BPS_TARGET_CSS = 'li[id*="menu-item-"] a'
def self.bps_global_navi
doc = Nokogiri::HTML(open(BPS_SITE_URL)) # スクレイピング先のURLを指定
navi_list = Array.new
doc.css(BPS_TARGET_CSS).each do |link| #
navi_list << link.content
end
return navi_list
end
end
Railsコンソールで実行した結果
=> ["Home", "会社概要", "Ruby on Rails", "EPUB電子書籍", "漫画翻訳", "MANGAREBORN", "SEO対策", "開発ブログ", "採用", "お問い合わせ"]
自動読み込みの設定
lib/以下のファイルは自動で読み込まれません。Controller等で使う場合は自動で読み込むようにしておくと楽です。
config/application.rbに以下を追加
コラム
社内で簡単にCSSパスをコピーする方法が挙がったので記載しておきます。
CSSパスをコピーする
CSSパスを自分で読み取って書くのが面倒な人はブラウザの機能を使って目的の要素のCSSパスを簡単にコピーすることができます。
■ Firefox(28.0)
右クリック=>要素を調査=>目的とする要素で右クリック=>一意なセレクタをコピー
・画像のところでコピーした結果
#menu-item-7532 > a:nth-child(1)
■ Chrome(34.0.1847.116 m)
右クリック=>要素を検証=>目的とする要素で右クリック=> Copy CSS path
・画像のところでコピーした結果
#menu-item-7532 > a
■ IE11
F12で開発者ツールが出るのですが、CSSパスをコピーするようなのは見つからなかったです。
まとめ
Nokogiriを使うことでかなり簡単にサイトの情報を取得することができるので、
サイトから情報を取得するような機能を作成する場合はNokogiriがおすすめです。