【问题标题】:Ruby Mechanize, Nokogiri and Net::HTTPRuby Mechanize、Nokogiri 和 Net::HTTP
【发布时间】:2012-08-16 08:10:18
【问题描述】:

我正在使用 Net::HTTP 处理 HTTP 请求并得到响应:

uri = URI("http://www.example.com")
http = Net::HTTP.start(uri.host, uri.port, proxy_host, proxy_port)
request = Net::HTTP::Get.new uri.request_uri
response = http.request request # Net::HTTPResponse object
body = response.body

如果我必须使用 Nokogiri gem 来解析这个 HTML 响应,我会这样做:

nokogiri_obj = Nokogiri::HTML(body)

但如果我想使用 Mechanize gem,我需要这样做:

agent = Mechanize.new
mechanize_obj = agent.get("http://www.example.com")

我是否可以使用 Net::Http 获取 HTML 响应,然后使用 Mechanize gem 将其转换为 Mechanize 对象,而不是使用 agent.get()


编辑:

绕过agent.get() 方法的原因是因为我试图使用EventMachine::Iterator 来发出并发EM-HTTP 请求。

EventMachine.run do
  EM::Iterator.new(urls, 3).each do |url,iter|
    puts "giving   #{url}   to httprequest now"
    http = EM::HttpRequest.new(url).get
    http.callback { |resp|
      uri = resp.send(:URI, url)
      puts "inside callback of #{url}"
      body = resp.response
      page = agent.parse(uri, resp, body)
    }
    iter.next
  end
end

但它不起作用。我收到一个错误:

/usr/local/rvm/gems/ruby-1.9.3-p194/gems/mechanize-2.5.1/lib/mechanize.rb:1165:in`parse': undefined method `[]' for #<EventMachine::HttpClient:0x0000001c18eb30> (NoMethodError)

当我对Net::HTTP 使用parse 方法时,它工作正常,我得到了 Mechanize 对象:

 uri = URI("http://www.example.com")
 http = Net::HTTP.start(uri.host, uri.port, proxy_host, proxy_port)
 request = Net::HTTP::Get.new uri.request_uri
 response = http.request request # Net::HTTPResponse object
 body = response.body
 agent = Mechanize.new
 page = agent.parse(uri, response, body)     

我在使用 em-http 时是否为 parse 方法传递了错误的参数?

【问题讨论】:

  • 您为什么要这样做? agent.get 要简单得多。
  • 你做的工作太多了。 Mechanize 将为您处理get。 Mechanize 还在内部使用 Nokogiri 进行解析,因此可以请求 Nokogiri 解析的文档让您进行额外的查找。
  • 我已经编辑了这个问题..谢谢

标签: ruby nokogiri mechanize eventmachine net-http


【解决方案1】:

我不确定您为什么认为使用 Net::HTTP 会更好。 Mechanize 将处理重定向和 cookie,并提供对 Nokogiri 已解析文档的随时访问。

require 'mechanize'

agent = Mechanize.new
page = agent.get('http://www.example.com')

# Use Nokogiri to find the content of the <h1> tag...
puts page.at('h1').content # => "Example Domains"

请注意,设置 user_agent 不是访问 example.com 所必需的。


如果您想使用线程引擎来检索页面,请查看Typhoeous and Hydra

【讨论】:

  • 是的..实际上我稍后在代码中以相同的方式使用 Mechanize 来抓取所需的数据。但我想知道我是否可以将 em-http 与问题中提到的 mechanize 结合使用..
  • 我推荐使用 Typhoeus。在我的回答中查看我的附加评论。
【解决方案2】:

看起来Mechanize 有一个parse method,所以这可以工作:

mechanize_obj = Mechanize.parse(uri, response, body)

【讨论】:

  • 感谢@Casper..Mechanize.parse 方法适用于 Net::HTTP...我怎样才能对 em-http 使用相同的方法?我想我在使用 em-http.. 时将错误的参数传递给“解析”方法
  • @Gameboy 我会针对该问题发布一个新问题。我不确定em-http 的响应类是否与Net::HTTP 响应兼容,这是Mechanize 所期望的。您可能需要修补某些东西或将响应转换为兼容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 2012-04-15
  • 2012-02-03
  • 2014-03-18
相关资源
最近更新 更多