0

我正在尝试使用 Hpricot 解析 HTML 表格,但被卡住了,无法从具有指定 ID 的页面中选择表格元素。

这是我的红宝石代码:-

require 'rubygems'
require 'mechanize'
require 'hpricot'

agent = WWW::Mechanize.new

page = agent.get('http://www.indiapost.gov.in/pin/pinsearch.aspx')

form = page.forms.find {|f| f.name == 'form1'}
form.fields.find {|f| f.name == 'ddl_state'}.options[1].select
page = agent.submit(form, form.buttons[2])

doc = Hpricot(page.body)

puts doc.to_html # Here the doc contains the full HTML page

puts doc.search("//table[@id='gvw_offices']").first # This is NIL

谁能帮我确定这有什么问题。

4

2 回答 2

1

Mechanize 将在内部使用 hpricot(它是 mechanize 的默认解析器)。更重要的是,它会将 hpricot 的东西传递给解析器,所以你不必自己做:

require 'rubygems'
require 'mechanize'

#You don't really need this if you don't use hpricot directly
require 'hpricot'

agent = WWW::Mechanize.new

page = agent.get('http://www.indiapost.gov.in/pin/pinsearch.aspx')

form = page.forms.find {|f| f.name == 'form1'}
form.fields.find {|f| f.name == 'ddl_state'}.options[1].select
page = agent.submit(form, form.buttons[2])

puts page.parser.to_html # page.parser returns the hpricot parser

puts page.at("//table[@id='gvw_offices']") # This passes through to hpricot

另请注意,page.search("foo").first相当于page.at("foo").

于 2009-03-20T20:40:00.060 回答
1

请注意,在更高版本(0.9.0)中,Mechanize 默认不再使用 Hpricot(它使用 Nokogiri),您必须明确指定 Hpricot 才能继续使用:

  WWW::Mechanize.html_parser = Hpricot

就像这样,Hpricot 周围没有引号或任何东西 - 可能有一个您可以为 Hpricot 指定的模块,因为如果您将此语句放在您自己的模块声明中,它将不起作用。这是在课堂上做到这一点的最佳方法(在打开模块或课堂之前)

require 'mechanize'
require 'hpricot'

# Later versions of Mechanize no longer use Hpricot by default
# but have an attribute we can set to use it
begin
  WWW::Mechanize.html_parser = Hpricot
rescue NoMethodError
  # must be using an older version of Mechanize that doesn't
  # have the html_parser attribute - just ignore it since 
  # this older version will use Hpricot anyway
end

通过使用救援块,您可以确保如果他们确实有旧版本的 mechanize,它不会因不存在的 html_parser 属性而烦恼。(否则你需要让你的代码依赖于最新版本的 Mechanize)

同样在最新版本中,不推荐使用 WWW::Mechanize::List。不要问我为什么,因为它完全破坏了语句的向后兼容性,例如

page.forms.name('form1').first

这曾经是一个常见的习惯用法,因为 Page#forms 返回了一个具有“名称”方法的机械化列表。现在它返回一个简单的表单数组。

我发现这一点很困难,但是您的用法会起作用,因为您使用find的是数组方法。

但是查找具有给定名称的第一个表单的更好方法是Page#form使您的表单查找行变为

form = page.form('form1')

此方法适用于旧版本和新版本。

于 2009-04-03T10:47:38.833 回答