ウェブ-HACKS 「とりあえずやってみよう!」ブログでタグ「hpricot」が付けられているもの
何度も同じようなプログラム(Rubyでスクレーピング)を作成しているような気がしますが、久々のRubyでクローラー作成。なんでこんなに何度も書くのかというと結構チェックしたいサイトが多く、仕事でも頼まれるためです。
※Perlで作成したクローラーはこちら
今回はきっちりクラスらしく作りました。結構汎用的になっているのではないかと思います。簡単なスクリプトです。
ソースはこれまで通りクリエイティブコモンズで。
かなり以下のサイト参考になります。何度も読ませて頂きました。
【参考サイト】
※Perlで作成したクローラーはこちら
今回はきっちりクラスらしく作りました。結構汎用的になっているのではないかと思います。簡単なスクリプトです。
ソースはこれまで通りクリエイティブコモンズで。
#!/usr/bin/ruby -Ks
require 'hpricot'
require 'mechanize'
require 'kconv'
$KCODE = 's'
class Crawler
def initialize(wait_time, internal, ngwords)
@agent = WWW::Mechanize.new
@wait_time = wait_time
@internal = internal
@ngwords = ngwords
@links = []
end
def http_connect(url)
print "OK\n"
@page = @agent.get(url)
end
def crawl(root)
@page = @agent.get(root)
@page.links.with.href(%r{}).each{|link|
if link.href =~ /^http/
url = link.href
else
%r|http://([^/]*)/| =~ root
url = 'http://' + $1 + '/' + link.href
end
@links << url.sub(/#.*$/,'')
}
@links.uniq!.delete(root)
puts @links
@links.each{|link|
begin
print link if $DEBUG
next unless access_test?(link)
http_connect(link)
sleep @wait_time
rescue => ex
puts ex.message
end
}
end
private
def access_test?(link)
unless %r|#{@internal}| =~ link
print "External Link.\n"
return false
end
@ngwords.each{|ng|
if /#{ng}/ =~ link
print "NG Word\n"
return false
end
}
true
end
end
かなり以下のサイト参考になります。何度も読ませて頂きました。
【参考サイト】
- Rubyでスクレーピング(mechanizeとhpricot)
- Perlでクロールする(LWP::UserAgent)
- RubyScraping - FrontPage
- Greenbear Diary - RubyでHTMLとWebを操作するためのライブラリ、HpricotとWWW::Mechanize , HikiReload
以前にPerlでクロールするプログラムを作ったので、勉強がてら今回はRubyで作成してみました。ただ今回はかなり、てこずりました。文字コード?のところではまってしまい作るのにまるまる1日かかりました。まずは出来上がったコード。
【事前準備】
【ソースコード】
ECショップの検索結果から商品情報を取得することを想定しているのですが、どうもカタカナの「ッ」が全て文字化けしてしまう。kconvではなくnkf、iconvを使っても結果はおなじ。解決方法としては以下1行を挿入するだけで文字化けはおきなくなりました。
原因はまだ調べているところですが、以下サイトをきちんと理解できればわかると思います。はぁー、大分はまってしまった。
【参考サイト】
【事前準備】
$ gem install hpricot $ gem install mechanize
【ソースコード】
#!/usr/bin/ruby -Ks
require 'hpricot'
require 'mechanize'
require 'kconv'
require 'jcode'
$KCODE = 's'
# 初期設定
@user_agent = 'Mac Safari'
@wait_time = 5
@url = 'taget_url'
def http_connect(url, keyword)
puts url if $DEBUG
@page = nil;@price = nil;@content = ""
begin
@agent = WWW::Mechanize.new
@agent.user_agent_alias = @user_agent
@page = @agent.get(url)
rescue
puts "#{keyword}#{@drim}CONNECTION ERROR"
return
end
link = @page.links.with.href(%r{http://target_url/\w+?/}).last
puts link.href if $DEBUG
if(link == nil || link.href.empty?)
puts "#{keyword}#{@drim}LINKERROR"
return
end
@page = @agent.click(link)
doc = @page.root
@name = (doc/"span.item_name").inner_html.tosjis
(doc/"span.item").each {|item|
item_str = item.inner_html.tosjis
item_str.scan(/(.*?)<\/div>(.*?)<\/div>/){|title, content|
@content += ":#{title}:#{content}" # if $DEBUG
}
item_str.scan(/([\d+] 円)/){|price|
@price = price
}
puts "#{keyword}#{@drim}#{@price}#{@drim}#{@name}#{@drim}#{@content}#{@drim}#{link.href}"
}
end
def generate_url
puts ARGV[0] if $DEBUG
File.open(ARGV[0]){|f|
f.each{|line|
keyword = line.chomp!
puts keyword if $DEBUG
target="#{@targeturl}?keyword=#{keyword}"
http_connect(target, keyword)
sleep @wait_time
}
}
end
puts @header
generate_url
ECショップの検索結果から商品情報を取得することを想定しているのですが、どうもカタカナの「ッ」が全て文字化けしてしまう。kconvではなくnkf、iconvを使っても結果はおなじ。解決方法としては以下1行を挿入するだけで文字化けはおきなくなりました。
require 'jcode'
原因はまだ調べているところですが、以下サイトをきちんと理解できればわかると思います。はぁー、大分はまってしまった。
【参考サイト】

