2012-02-18 69 views
0

我必須閱讀可通過http進行身份驗證的xml文件。這就是我使用機械化的原因。(Rails)無法獲得Mechanize正確讀取Web xml文件

我的問題是我無法機械識別這些XML文件,所以我可以使用.find或.search對它們進行操作。

這是我第一次嘗試 - 在我看來,(HTML文件)

<% agent = Mechanize.new %>

<% page = agent.get("http://dl.dropbox.com/u/344349/xml.xml") %>

<%= page %>

它返回#<Mechanize::File:0x007f9dd602de30>。這::File而不是::Page 我不能使用.find或.search這個,因爲它會與undefined method find for #<Mechanize::File:0x007f9dd624cbd0>

機械化文檔錯誤說:這是可插拔解析器默認值(和底座)類。如果機械化無法找到用於內容類型的適當類,則將使用此類。例如,如果你下載JPG,Mechanize將不知道如何解析它,所以這個類將被實例化。

所以我創建了一個類如下所述:http://rdoc.info/github/tenderlove/mechanize/master/Mechanize/PluggableParser

My class

class XMLParser < Mechanize::File

attr_reader :xml

def initialize(uri=nil, response=nil, body=nil, code=nil)

super(uri, response, body, code)

@xml = xml.parse(body)

end

end

,並在我看來,更新的代碼(HTML文件)

<% agent = Mechanize.new %>

<% agent.pluggable_parser['text/xml'] = XMLParser %>

<% agent.user_agent_alias = 'Windows Mozilla' %>

<% page = agent.get("http://dl.dropbox.com/u/344349/xml.xml") %>

<%= page %>

甚至

<% agent = Mechanize.new %>

<% agent.pluggable_parser.xml = XMLParser %>

<% page1 = agent.get('http://dl.dropbox.com/u/344349/xml.xml') # => CSVParser %>

<%= page1 %>

仍返回#<Mechanize::File:0x007f9dd5253b48>

我甚至測試確切的代碼(CSVParser - http://rdoc.info/github/tenderlove/mechanize/master/Mechanize/PluggableParser),並試圖加載一個仍然被視爲一個::文件csv文件。

我在做什麼錯?

回答

2

好的,所以我剛剛爲自己解決了這個問題。解決方案分爲兩部分:

首先,您匹配的內容類型不正確。如果你運行這一行,你做你的GET後,它會告訴你的內容類型是什麼,你所得到的文件:

page.response['content-type'] # => 'application/xml', not 'text/xml' 

當我使用機械化,讓您的網頁(的「http:// DL .dropbox.com/u/344349/xml.xml'),我看到'application/xml'作爲內容類型。

其次,您沒有正確使用PluggableParser。在這裏使用XMLParser將生成NoMethodError: undefined method 'parse' for nil:NilClass。更改類定義使用引入nokogiri :: XML來代替:

class XmlParser < Mechanize::File 
    attr_reader :xml 
    def initialize(uri = nil, response = nil, body = nil, code = nil) 
    @xml = Nokogiri::XML(body) 
    super uri, response, body, code 
    end 
end 

然後,其設置爲解析器正確的內容類型:

mech.pluggable_parser['application/xml'] = XmlParser 

要使用此,你會得到你的頁面與之前相同,然後引用頁面對象的xml屬性作爲Nokogiri::XML::Document實例,該實例是Nokogiri::XML::Node的子類。幸運的是,Mechanize::Page.search只是Nokogiri::XML::Node.search的一個包裝,所以您可以按照您期望的相同方式進行搜索,非常多。就像這樣:

page.xml.search 'catalog' 

進一步的細化將是XmlParser.search映射到引入nokogiri .search方法:

page.search 'catalog' 

# This is the same as what Mechanize::Page does 
class XmlParser < Mechanize::File 
    extend Forwardable 
    def_delegators :@xml, :search, :/, :at 
end 

這使您可以直接在頁面實例執行您的搜索

+0

我不是100%完成,但它現在看起來工作。謝謝伯爵! – 2012-02-22 12:31:09

+0

非常感謝!這是一個拯救生命的人! – bloveless 2012-06-29 23:05:15