ウェブ-HACKS 「とりあえずやってみよう!」ブログでタグ「mechanize」が付けられているもの
以前に作ったRubyクローラーを改造して、検索フォームに自動で値を設定するプログラムをつくりました。その際にテキストフィールドのnameにハイフンがあり値の設定にはまったので解決方法を記載します。
以下ですとエラーとなります。 ※keyword-fieldにハイフンが入っているためです。
実は以下のように['keyword-field']とすればOK。簡単です。いろいろ検索したのですが、解決策が探せなかったので、記載してみました。
以下ですとエラーとなります。 ※keyword-fieldにハイフンが入っているためです。
page = @agent.get('http://example.com')
search_form = page.forms.with.action('http://example.com/search.html').first
search_form.keyword-field = keyword
実は以下のように['keyword-field']とすればOK。簡単です。いろいろ検索したのですが、解決策が探せなかったので、記載してみました。
page = @agent.get('http://example.com')
search_form = page.forms.with.action('http://example.com/search.html').first
search_form['keyword-field'] = keyword
何度も同じようなプログラム(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'
原因はまだ調べているところですが、以下サイトをきちんと理解できればわかると思います。はぁー、大分はまってしまった。
【参考サイト】
RubyでHTTPアクセスが正常にできるかどうかを確認するツールを作成しました。
対象のURLにアクセスし、titleの文字列で正常にページアクセスできるかどうか確認しています。
エラー時は指定したメールアドレスにメールをとばすようになっています。
以下にソースコードを記載します。
※下線部は適宜環境にあわせてください
Windows環境でおこないました。
デバッグモードで実行するといくつか警告がでてますね。なんでだろ?
とりあえず動作はします。
【事前準備】
gemsでmechanizeをインストールする
> gem install mechanize
【ソースコード】
【参考にしたサイトです】
対象のURLにアクセスし、titleの文字列で正常にページアクセスできるかどうか確認しています。
エラー時は指定したメールアドレスにメールをとばすようになっています。
以下にソースコードを記載します。
※下線部は適宜環境にあわせてください
Windows環境でおこないました。
デバッグモードで実行するといくつか警告がでてますね。なんでだろ?
とりあえず動作はします。
【事前準備】
gemsでmechanizeをインストールする
> gem install mechanize
【ソースコード】
#!/usr/bin/ruby
require 'mechanize'
require 'net/smtp'
require 'kconv'
url = "http://localhost/"
wait_time = 15
@from_address = "from@mail_domain"
@send_address = "send@mail_domain"
agent = WWW::Mechanize.new
def send_alert( msg )
body = [ "Subject: HTTP Access Error\n", "\n", msg ]
Net::SMTP.start('mail_server') do |smtp|
smtp.sendmail( body, @from_address, @send_address )
end
exit
end
begin
while 1
page = agent.get(url)
s = page.title.tosjis
if s =~ /match_word/
puts "#{url}: #{s}\n" if $DEBUG
else
puts "#{url}: #{s}=#{match_str.tosjis}\n" if $DEBUG
send_alert("#{url}: #{s}\n")
end
sleep wait_time
end
rescue => ex
puts "#{url}: #{ex.message}\n" if $DEBUG
send_alert("#{url}:#{ex.message}\n")
end
【参考にしたサイトです】

