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 は、以降のバージョン (0.9.0) ではデフォルトで 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 が「name」メソッドを持つ機械化リストを返したため、機能する一般的なイディオムでした。これで、フォームの単純な配列が返されます。

私はこれを難しい方法で見つけましたがfind、配列のメソッドを使用しているため、使用法は機能します。

しかし、与えられた名前を持つ最初のフォームを見つけるためのより良い方法はPage#form、フォーム検索行が

form = page.form('form1')

この方法は、古いバージョンと新しいバージョンで機能します。

于 2009-04-03T10:47:38.833 に答える
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 に答える