把Mechanize的html_parser改回到Hpricot

记得我最初开始用[url=http://nokogiri.org/]Nokogiri[/url]就是因为[url=http://mechanize.rubyforge.org/mechanize/]Mechanize[/url]用的HTML/XML解析器从[url=http://hpricot.com/]Hpricot[/url]转到了Nokogiri。不过Nokogiri用起来问题多多,内存泄漏的问题貌似一直没解决,之前在1.9上想用的时候也是segfault,然后对格式不良好的HTML的解析也有问题。虽说_why离开了人们的视野,但在[url=http://github.com/whymirror]whymirror[/url]上还能找到why留在github的代码,包括当前版本的[url=http://github.com/whymirror/hpricot]Hpricot[/url];通过RubyGems也还能安装到Hpricot。
最近在写某脚本的时候又被Nokogiri绊倒了,一怒,决定把机上的Mechanize的html_parser换回到Hpricot去。之前[url=http://night-stalker.iteye.com/]NS老兄[/url]已经这么做过一次,向他咨询了经验后,这改造工程顺利完成。下面把步骤记下来。

这次测试的机器上,我安装的是[url=http://rubyforge.org/frs/?group_id=167&release_id=38052]RubyInstaller Technology Preview2[/url]的1.8.6-p383,安装到C:\Ruby。这个新的RubyInstaller装的Ruby上要安装Hpricot得先把devkit也装上才行,为了构建Hpricot用。下载[url=http://rubyforge.org/frs/?group_id=167&release_id=38052]devkit-3.4.5r3-20090411.7z[/url],解压到Ruby的安装目录,然后从devkit目录里的MSys来完成后面需要命令行的步骤。通过
gem install mechanize

可以安装到Mechanize 0.9.3,然后同样
gem install hpricot

可以安装到Hpricot 0.8.2。
如果是用老的官方版RubyInstaller装的Ruby 1.8.6则不需要devkit,直接用RubyGems就能装上Hpricot。如果你用的是自己构建出来的Ruby的话想必这些gem要怎么构建也该了解。下面描述的步骤也对应非Windows用户,因为只涉及纯Ruby代码的修改。

都装好之后,把下面提到的几个地方改过来:(注释里的是原本的代码,上面是新改的代码)

C:\Ruby\lib\ruby\gems\1.8\specifications\mechanize-0.9.3.gemspec
C:\Ruby\lib\ruby\gems\1.8\gems\mechanize-0.9.3\mechanize.gemspec
s.add_runtime_dependency(%q<hpricot>, [">= 0.8.2"])
# s.add_runtime_dependency(%q<nokogiri>, [">= 1.2.1"])
# ...
s.add_dependency(%q<hpricot>, [">= 0.8.2"])
# s.add_dependency(%q<nokogiri>, [">= 1.2.1"])

(这两个文件里有多处相同的代码要改,不放心的话在文件里搜一下吧)

C:\Ruby\lib\ruby\gems\1.8\gems\mechanize-0.9.3\lib\www\mechanize.rb
require 'hpricot'
# require 'nokogiri'

@html_parser = Hpricot
# @html_parser = Nokogiri::HTML


C:\Ruby\lib\ruby\gems\1.8\gems\mechanize-0.9.3\lib\www\mechanize\page.rb
      def parser
return @parser if @parser

if body && response
#if mech.html_parser == Nokogiri::HTML
# @parser = mech.html_parser.parse(html_body, nil, @encoding)
#else
@parser = mech.html_parser.parse(html_body)
#end
end

@parser
end


C:\Ruby\lib\ruby\gems\1.8\gems\mechanize-0.9.3\lib\www\mechanize\util.rb
        def to_native_charset(s, code=nil)
#if Mechanize.html_parser == Nokogiri::HTML
# return unless s
# code ||= detect_charset(s)
# Iconv.iconv("UTF-8", code, s).join("")
#else
s
#end
end

def from_native_charset(s, code)
#if Mechanize.html_parser == Nokogiri::HTML
# return unless s
# Iconv.iconv(code, "UTF-8", s).join("")
#else
s
#end
end


Mechanize的设计原本就考虑到了html_parser的切换,所以改起来并不费力。只是page.rb和util.rb里显式写了Nokogiri::HTML这点让人郁闷,要是去掉了require 'nokogiri'这些代码就会抱怨Nokogiri常量未定义。

幸好改造前先问了NS,不然我大概不知道要去改gemspec里的配置。以前一直没了解过RubyGems是怎么工作的orz

091109更新:刚试了在JRuby 1.4.0上用同样方式改造Mechanize让它用Hpricot 0.8.2-java来做html_parser,暂时没遇到什么问题。终于又可以在JRuby上用Mechanize了,泪目 TvT
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值