Railsメモ(6) : Nokogiriでスクレイピングする
Bootswatchで見た目はよくなったがデータ数が少ないので、ここからはデータを増やす作業をする。
rails consoleで1個1個追加なんてしていられないので、NokogiriでWikipediaのページをスクレイピングした結果をCSVファイルに出力してまとめて追加する。
Nokogiri
RubyでWebページをスクレイピングするならNokogiriを使用するのがよいらしい。
Wikipediaのページからランキング情報をスクレイピングするが、毎回アクセスするのも時間がかかるので下記コマンドでローカルにダウンロードしておく。
$ wget https://en.wikipedia.org/wiki/Billboard_Year-End_Hot_100_singles_of_2014 -O 2014.html
Nokogiriが動作するか試しにタイトルを抽出してみる。
require 'nokogiri' f = File.open("2014.html") doc = Nokogiri::HTML(f) f.close() puts doc.title
$ ruby nokogiri_test.rb Billboard Year-End Hot 100 singles of 2014 - Wikipedia, the free encyclopedia
動作することは確認できたので、ランキング情報を抜き出す方法を検討する。
まずHTMLの構造を把握するためにChromeで右クリック→"要素の検証"からデベロッパーツールを起動する。
虫眼鏡アイコンをクリックしてから1位の"Happy"を選択すると画面下部にHTMLの構造が表示される。どうやらtable.wikitable.sortable
が目的のtableらしいので抽出してみる。
NokogiriにはXPathとCSSセレクタがあるが、CSSセレクタの方が記述が簡単らしいのでそちらを使用する。
require 'nokogiri' f = File.open("2014.html") doc = Nokogiri::HTML(f) f.close() doc.css("table.wikitable.sortable tr").each do |node| puts node end
$ ruby nokogiri_test.rb <tr> <th scope="col" style="background:#dde;"> <center>№</center> </th> <th scope="col" style="background:#dde;">Title</th> <th scope="col" style="background:#dde;">Artist(s)</th> </tr> <tr> <th scope="row">1</th> <td>"<a href="/wiki/Happy_(Pharrell_Williams_song)" title="Happy (Pharrell Williams song)">Happy</a>"</td> <td><a href="/wiki/Pharrell_Williams" title="Pharrell Williams">Pharrell Williams</a></td> </tr> …省略… <tr> <th scope="row">100</th> <td>"<a href="/wiki/Adore_You" title="Adore You">Adore You</a>"</td> <td><a href="/wiki/Miley_Cyrus" title="Miley Cyrus">Miley Cyrus</a></td> </tr>
いい感じに抽出できているようなので、あとはランキングとタイトル、アーティスト名を抽出してCSVに出力する。なおtr
タグの1番目はヘッダ情報なのでスキップする。
Wikipediaには1951年からのランキングがあるが、古いのはあまり興味がないのでキリのいいところで1990年からの25年分を抽出してみる。
require 'nokogiri' require 'csv' CSV.open("seed_songs.csv", "w") do |csv| for year in 1990..2014 do f = File.open("#{year}.html") doc = Nokogiri::HTML(f) f.close() doc.css("table.wikitable tr").each_with_index do |node, index| next if index == 0 ranking = node.css("th").inner_text title = node.css("td:eq(1)").inner_text.gsub(/^"/, "").gsub(/"$/, "") artist = node.css("td:eq(2)").inner_text csv << [title, artist, ranking, year] end end end
$ ruby nokogiri_test.rb $ wc -l seed_songs.csv 2500 seed_songs.csv $ head -n 5 seed_songs.csv Hold On,Wilson Phillips,1,1990 It Must Have Been Love,Roxette,2,1990 Nothing Compares 2 U,Sinéad O'Connor,3,1990 Poison,Bell Biv DeVoe,4,1990 Vogue,Madonna,5,1990 $ tail -n 5 seed_songs.csv Studio,ScHoolboy Q featuring BJ the Chicago Kid,96,2014 0 to 100 / The Catch Up,Drake,97,2014 I Don't Dance,Lee Brice,98,2014 Somethin' Bad,Miranda Lambert and Carrie Underwood,99,2014 Adore You,Miley Cyrus,100,2014
ちゃんと2,500件抽出できているので、次ステップでこのデータをDBに追加してみる。
- 作者: すがわらまさのり,前島真一,近藤宇智朗,橋立友宏
- 出版社/メーカー: 技術評論社
- 発売日: 2014/06/06
- メディア: 大型本
- この商品を含むブログ (8件) を見る