1. 概要
実はこのあたりが最終目標へ向かう方法なのだ。
本項は以下のサイトを参考にさせていただきました。
「[Ruby] Nokogiri を使って、ページ内全ての a タグの href 属性の値を取得する」
「nokogiri をつかってリンクを取得」
2. <a href=""> を取得
参考サイトに習って <a href=""> 内のリンク先を取得して表示してみます。
#!/usr/bin/env ruby
require 'open-uri'
require 'nokogiri'
url = ARGV[0]
html = open(url).read
html.sub!(/^<!DOCTYPE html(.*)$/, '<!DOCTYPE html>')
doc = Nokogiri::HTML(html)
doc.css('a').each do |anchor|
puts anchor[:href]
end
実行してみます。
> ./ソースファイル名.rb http://freebsd.sing.ne.jp/lang/ruby/04/02.html
#4.2.1
#4.2.2
#4.2.3
http://keruuweb.com/ruby-openuri%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/
https://qiita.com/Linus_MK/items/94280dc000726f740c3c
http://mofuken.blogspot.jp/2012/12/ruby-open-uri-https-certificate-verify.html
https://gist.github.com/toshiharu/5539841
https://qiita.com/whiteleaf7@github/items/4504b208ad2eec1f9357
をを、出てくる出てくる。
3. <input onclick=""> を取得
本サイトの場合
<input type="submit" class="page" value="前 へ" onclick="location.href='./01.html'">
<input type="submit" class="page" value="戻 る" onclick="location.href='./'">
<input type="submit" class="page" value="次 へ" onclick="location.href='./03.html'">
という書き方でページ送りをしているので「<input onclick="">」の「location.href=''」の中身もリンク先として取得したいのです。
さすがにここらで少しは頭を使わないとね。
前項の14行以降を書き換えるとして
doc.css('input').each do |anchor| # input の中身を取り出し
s = anchor[:onclick] # onclick の中身を取り出し
s = s[/\'.*\'/] # ' で囲まれた部分を取り出し
s.delete!("'") # ' を削除
puts s
end
同様に実行してみると
> ./ソースファイル名.rb http://freebsd.sing.ne.jp/lang/ruby/04/02.html
./01.html
./
./03.html
もっとスマートな書き方があるはずであるが先を急ぐのでここはよしとする。
ちょっと訂正、別のページでやったときに
> ./ソースファイル名.rb http://freebsd.sing.ne.jp/windows/01/01.html
./test08.rb:21:in `block in <main>': undefined method `[]' for nil:NilClass (NoMethodError)
from /usr/local/lib/ruby/gems/2.4/gems/nokogiri-1.8.2/lib/nokogiri/xml/node_set.rb:190:in `block in each'
from /usr/local/lib/ruby/gems/2.4/gems/nokogiri-1.8.2/lib/nokogiri/xml/node_set.rb:189:in `upto'
from /usr/local/lib/ruby/gems/2.4/gems/nokogiri-1.8.2/lib/nokogiri/xml/node_set.rb:189:in `each'
from ./test08.rb:19:in `<main>'
こけちゃった。
これは「<input>」内で onclick がないものがあるので、そこでこけている。
onclick がある場合のみ処理を行います。
doc.css('input').each do |anchor| # input の中身を取り出し
if s = anchor[:onclick] # onclick の中身を取り出し
s = s[/\'.*\'/] # ' で囲まれた部分を取り出し
s.delete!("'") # ' を削除
puts s
end
end
4. イメージのリンクを取得
次は、以下のように書いてある
</pre><div><a href="/img/FreeBSD/windows/01/01/01.png"><img src="/img/FreeBSD/windows/01/01/01.png" width="289" height="470" title="クリックでオリジナルのサイズで開きます"></a></div><pre>
イメージファイルのリンクを取得します。
こちらは前項より簡単、同様に
doc.css('img').each do |anchor|
puts anchor[:src]
end
これで OK だな。
実行すると
> ./ソースファイル名.rb http://freebsd.sing.ne.jp/windows/01/01.html
/img/FreeBSD/adv/small01.png
/img/FreeBSD/adv/small03.png
/img/FreeBSD/windows/01/01/01.png
/img/FreeBSD/windows/01/01/02.png
/img/FreeBSD/windows/01/01/03.png
/img/FreeBSD/windows/01/01/04.png
/img/adv/google01.png
/img/FreeBSD/adv/middle02.png
/img/adv/admax02.png
/img/adv/google02.png
/img/adv/admax03.png
/img/adv/google04.png
/php/count.php?df=freebsd&sh=F
予定通りです。
5. まとめて配列にぶち込む
前項までのものをまとめて配列にぶち込みたいと思います。
#!/usr/bin/env ruby
require 'open-uri'
require 'nokogiri'
url = ARGV[0]
html = open(url).read
html.sub!(/^<!DOCTYPE html(.*)$/, '<!DOCTYPE html>')
doc = Nokogiri::HTML(html)
link = []
doc.css('a').each do |anchor|
link.push(anchor[:href])
end
doc.css('input').each do |anchor|
if s = anchor[:onclick]
s = s[/\'.*\'/]
link.push(s.delete!("'"))
end
end
doc.css('img').each do |anchor|
link.push(anchor[:src])
end
puts link.sort
これを実行すると
> ./ソースファイル名.rb http://freebsd.sing.ne.jp/windows/01/01.html
#1
#2
./
./02/
/img/FreeBSD/adv/middle02.png
/img/FreeBSD/adv/small01.png
/img/FreeBSD/adv/small03.png
/img/FreeBSD/windows/01/01/01.png
/img/FreeBSD/windows/01/01/01.png
/img/FreeBSD/windows/01/01/02.png
/img/FreeBSD/windows/01/01/02.png
/img/FreeBSD/windows/01/01/03.png
/img/FreeBSD/windows/01/01/03.png
/img/FreeBSD/windows/01/01/04.png
/img/FreeBSD/windows/01/01/04.png
/img/adv/admax02.png
/img/adv/admax03.png
/img/adv/google01.png
/img/adv/google02.png
/img/adv/google04.png
/php/count.php?df=freebsd&sh=F
http://net-3.blogspot.jp/2013/03/blog-post_16.html
うむ、予定通り。
6. 分類する
前項までで収集したものを分類したいと思います。
末尾を変更します。
link.sort!
for item in link do
case item[0]
when '#'
puts "ページ内リンク => #{item}"
when 'h'
puts "外部 リンク => #{item}"
else
if item[-3, 3] == 'png'
puts "イメージファイル => #{item}"
elsif item[-4, 4] == 'html' || item[-1, 1] == '/'
puts "内部 リンク => #{item}"
else
puts " => #{item}"
end
end
end
これを実行すると
> ./ソースファイル名.rb http://freebsd.sing.ne.jp/windows/01/01.html
ページ内リンク => #1
ページ内リンク => #2
内部 リンク => ./
内部 リンク => ./02/
イメージファイル => /img/FreeBSD/adv/middle02.png
イメージファイル => /img/FreeBSD/adv/small01.png
イメージファイル => /img/FreeBSD/adv/small03.png
イメージファイル => /img/FreeBSD/windows/01/01/01.png
イメージファイル => /img/FreeBSD/windows/01/01/01.png
イメージファイル => /img/FreeBSD/windows/01/01/02.png
イメージファイル => /img/FreeBSD/windows/01/01/02.png
イメージファイル => /img/FreeBSD/windows/01/01/03.png
イメージファイル => /img/FreeBSD/windows/01/01/03.png
イメージファイル => /img/FreeBSD/windows/01/01/04.png
イメージファイル => /img/FreeBSD/windows/01/01/04.png
イメージファイル => /img/adv/admax02.png
イメージファイル => /img/adv/admax03.png
イメージファイル => /img/adv/google01.png
イメージファイル => /img/adv/google02.png
イメージファイル => /img/adv/google04.png
=> /php/count.php?df=freebsd&sh=F
外部 リンク => http://net-3.blogspot.jp/2013/03/blog-post_16.html