繁体   English   中英

(滑轨)无法机械化以正确读取Web xml文件

[英](Rails) Can't get Mechanize to correctly read a web xml file

我必须阅读可通过带有身份验证的http访问的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>出错

Mechanize doc说:这是可插拔解析器的默认(和基本)类。 如果Mechanize无法找到适合于内容类型的类,则将使用该类。 例如,如果下载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),并尝试加载仍被视为:: File的csv文件。

我究竟做错了什么 ?

好的,现在我已经为自己解决了这个问题。 解决方案分为两部分:

首先,您要匹配的内容类型不正确。 如果运行此行,获取后,它将告诉您所获取文档的内容类型是什么:

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方法:

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

这使您可以直接在页面实例上执行搜索:

page.search 'catalog'

您可以将解析器更改为使用Page类,如下所示:

agent = Mechanize.new
agent.pluggable_parser.default = Mechanize::Page
agent.get("http://dl.dropbox.com/u/344349/xml.xml").class # Mechanize::Page

参见http://mechanize.rubyforge.org/Mechanize/PluggableParser.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM