この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
初投稿、新卒のいくたです。よろしくお願いします。
新一くんの声が好きなので、そればっかり見たいのです。
バーローなのです。
準備するもの
実装の概要
今回は、名探偵コナンの非公式ファンサイト「名探偵コナン応援サイト 毛利小五郎探偵事務所」から過去のアニメ各話の情報をとってきます。
とってきたデータをrubyのgemであるNokogiriでスクレイピング(解析)します。
ノコギリでギコギコ切って、必要なところ(新一くん登場回)だけを表示させる。
ざっくり言うとそんなイメージです。
コナン…ノコギリ…バラバラ死体…
なんだか事件の匂いがしますね。
webページの情報をとってくる
試しに以下のページをとってきて表示してみます。
名探偵コナン 事件データ・1996年度(TVアニメ)
# shinichi.rb
require 'open-uri' # open-uriライブラリを読み込みます
url = 'http://conan.aga-search.com/anime/1996/'
html = open(url).read # open-uriのおかげでURL先のデータを普通のファイルと同様に扱えます
puts html
実行結果
$ ruby shinichi.rb
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>名探偵コナン 事件データ・1996年度(TVアニメ)</title>
(省略)
Webページがhtmlの形式でとってこられました。
Nokogiri の使い方
表の各話の登場人物の項目に着目して、’新一’を含む行だけを抜き出します。
# shinichi.rb
require 'open-uri'
require 'nokogiri'
url = 'http://conan.aga-search.com/anime/1996/'
html = open(url).read
doc = Nokogiri::HTML.parse(html)
trs = doc.xpath('//*[@id="leftpane"]/table[2]/tbody/tr[contains(.,'新一')]')
今回の肝となる、’新一’を含む行だけ抜き出す処理を見ていきましょう。
doc.xpath('//*[@id="leftpane"]/table[2]/tbody/tr[contains(.,'新一')]')
XpathとはHTMLのような木構造の分岐点(ノード)を指し示す表現です。
Xpathメソッドで抜き出すノードを指定できます。
自分の好きなところでXpathを指定しようとすると、HTMLを見てidやらタグやらを確認することになります。
これが正直めんどくさいんです…
が!実はXpathを指定する複雑なパターンを自分で考えなくても、簡単に好きな要素を抽出できるんです!
次は、Chromeを使ったXpathのパターン取得方法をご紹介しましょう。
Xpathパターンはchromeが知っている
chromeで解析したいwebページを開き、デベロッパーツールを表示させます。
Elementsタブから抽出したい要素を右クリックして、Copy > Copy Xpath を選びます。
図1 Xpathの指定パターン取得方法
//*[@id="leftpane"]/table[2]/tbody
HTMLをいちいち読まなくても、特定の要素を指定するパターンをchromeが教えてくれるのです。便利!
あとは抽出する条件を付け加えるだけです。
今回は’新一’という文字列を含むtrタグの内容をとってくるので、以下のように条件を追加します。
//*[@id="leftpane"]/table[2]/tbody/tr[contains(.,'新一')]
こちらの記事にいろんな指定方法がまとめられます。
詳しく知りたい方はどうぞ〜
最後の仕上げ
最後にとってきたデータの形を整えて出力します。
# shinichi.rb
require 'open-uri'
require 'nokogiri'
url = 'http://conan.aga-search.com/anime/1996/'
html = open(url).read
doc = Nokogiri::HTML.parse(html)
trs = doc.xpath('//*[@id="leftpane"]/table[2]/tbody/tr[contains(.,'新一')]')
# HTMLの解析結果をtr要素ごとに処理します
trs.each do |tr|
td = tr.xpath('./td') # tdタグを取り出します
story_number = td[0].text # tdタグの1番目の要素のテキストを取り出します
story_title = td[1].text # tdタグの2番目の要素のテキストを取り出します
puts "名探偵コナン 第#{story_number}話 #{story_title}"
end
実行結果
$ ruby shinichi.rb
名探偵コナン 第1話 ジェットコースター殺人事件
名探偵コナン 第2話 社長令嬢誘拐事件
名探偵コナン 第3話 アイドル密室殺人事件
名探偵コナン 第7話 月いちプレゼント脅迫事件
名探偵コナン 第10話 プロサッカー選手脅迫事件
名探偵コナン 第29話 コンピューター殺人事件
名探偵コナン 第32話 コーヒーショップ殺人事件
名探偵コナン 第33話 探偵団サバイバル事件
名探偵コナン 第42話 カラオケボックス殺人事件
新一くんが出ている回の話数とタイトルがとってこられました!
このキーワードを元に動画配信サイトで検索すれば、新一くんが出ている回だけを永遠見続けることができますね。
実は、新一くんと怪盗キッドは同じ声優さんが演じています。
‘キッド’を含む回も取って来られるように、条件を追加してもいいかもしれませんね。
それでは、今日はこの辺で。
読んでいただき、ありがとうございました。