to_absolute_uri
rubyのmechanizeで日本語が通らない。
# sample.rb
require "rubygems"
require "mechanize"
agent = WWW::Mechanize.new
agent.user_agent_alias='Windows Mozilla'
agent.get("http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8")
これを実行すると
>ruby sample.rb
ruby sample.rb
C:/opt/ruby-1.8/lib/ruby/1.8/uri/common.rb:432:in `split': bad URI(is not URI?): http://ja.wikipedia.org/wiki/繝。繧、繝ウ繝壹・繧ク (URI::InvalidURIError)
from C:/opt/ruby-1.8/lib/ruby/1.8/uri/common.rb:481:in `parse'
from C:/opt/ruby-1.8/lib/ruby/gems/1.8/gems/mechanize-0.6.4/lib/mechanize.rb:272:in `to_absolute_uri'
from C:/opt/ruby-1.8/lib/ruby/gems/1.8/gems/mechanize-0.6.4/lib/mechanize.rb:141:in `get'
from sample.rb:6
例外はmechanize.rbのto_absolute_uriというメソッドから。
#コード
def to_absolute_uri(url, cur_page=current_page())
url = URI.parse(
URI.unescape(Util.html_unescape(url.to_s.strip)).gsub(/ /, '%20')
) unless url.is_a? URI
# construct an absolute uri
if url.relative?
raise 'no history. please specify an absolute URL' unless cur_page.uri
url = cur_page.uri + url
end
return url
end
urlを
url → htmlでunescapeしたurl → htmlでunescapeしたurlをuriでunescapeしたurl
→ htmlでunescapeしたurlをuriでunescapeしたurlの空白文字を%20に置換したurl
と変更を繰り返してる。
ところで、なぜいったんURI.unescapeしたあと空白文字を%20に置換しているんだ?
これなら、
url → htmlでunescapeしたurl
で、いいはずなのに。
実際にto_absolute_uriのurlの部分を
url = URI.parse(
URI.unescape(Util.html_unescape(url.to_s.strip)).gsub(/ /, '%20')
) unless url.is_a? URI
から
url = URI.parse(
Util.html_unescape(url.to_s.strip)
) unless url.is_a? URI
を変更すると、上のsample.rbが動作する。
Mechanizeのメーリングリストを見てみると、このto_absolute_uriって変更要望がたくさん出ているんだよなぁ。。。
追記
既存のものを再定義すればいいわけだから、これでとりあえずしのげた。
require "rubygems"
require "mechanize"
module WWW
class Mechanize
def to_absolute_uri(url, cur_page=current_page())
url = URI.parse(
Util.html_unescape(url.to_s.strip)
) unless url.is_a? URI
# construct an absolute uri
if url.relative?
raise 'no history. please specify an absolute URL' unless cur_page.uri
url = cur_page.uri + url
end
return url
end
end
end
agent = WWW::Mechanize.new
agent.user_agent_alias='Windows Mozilla'
puts agent.get("http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8").body