首页 > 解决方案 > Net::HTTP 和 Nokogiri - nil:NilClass (NoMethodError) 的未定义方法“body”

问题描述

谢谢你的时间。对 OOP 和 Ruby 来说有些新意,在从几个不同的堆栈溢出答案综合解决方案之后,我已经扭转了局面。

我的目标是编写一个脚本,使用 Nokogiri 库解析 URL 的 CSV。在尝试使用 open-uri 和 open-uri-redirections 插件跟踪重定向但失败后,我选择了 Net::HTTP,这让我感动……直到我遇到了专门具有 302 重定向的 URL。

这是我用来参与 URL 的方法:

require 'Nokogiri'
require 'Net/http'
require 'csv'

def fetch(uri_str, limit = 10)
  # You should choose better exception.
  raise ArgumentError, 'HTTP redirect too deep' if limit == 0

  url = URI.parse(uri_str)
  #puts "The value of uri_str is: #{ uri_str}"
  #puts "The value of URI.parse(uri_str) is #{ url }"
  req = Net::HTTP::Get.new(url.path, { 'User-Agent' => 'Mozilla/5.0 (etc...)' })
  # puts "THE URL IS #{url.scheme + ":" + url.host + url.path}" # just a reporter so I can see if it's mangled
  response = Net::HTTP.start(url.host, url.port, :use_ssl => url.scheme == 'https') { |http| http.request(req) }
  case response
  when Net::HTTPSuccess     then  response
  when Net::HTTPRedirection then fetch(response['location'], limit - 1)
  else
    #puts "Problem clause!"
    response.error!
  end
end

在我的脚本中,我使用 URL csv 文件名的 ARGV,执行 CSV.read,将 URL 编码为字符串,然后使用 Nokogiri::HTML.parse 将其全部转换为我可以使用 xpath 选择器检查然后写入输出 CSV。

效果很好……只要我遇到 200 响应,不幸的是不是每个网站。当我遇到 302 时,我得到了这个:

C:/Ruby24-x64/lib/ruby/2.4.0/Net/http.rb:1570:in `addr_port': undefined method `+' for nil:NilClass (NoMethodError)
        from C:/Ruby24-x64/lib/ruby/2.4.0/Net/http.rb:1503:in `begin_transport'
        from C:/Ruby24-x64/lib/ruby/2.4.0/Net/http.rb:1442:in `transport_request'
        from C:/Ruby24-x64/lib/ruby/2.4.0/Net/http.rb:1416:in `request'
        from httpcsv.rb:14:in `block in fetch'
        from C:/Ruby24-x64/lib/ruby/2.4.0/Net/http.rb:877:in `start'
        from C:/Ruby24-x64/lib/ruby/2.4.0/Net/http.rb:608:in `start'
        from httpcsv.rb:14:in `fetch'
        from httpcsv.rb:17:in `fetch'
        from httpcsv.rb:42:in `block in <main>'
        from C:/Ruby24-x64/lib/ruby/2.4.0/csv.rb:866:in `each'
        from C:/Ruby24-x64/lib/ruby/2.4.0/csv.rb:866:in `each'
        from httpcsv.rb:38:in `<main>'

我知道我在我面前错过了一些东西,但我不知道我应该puts看看它是否为零。任何帮助表示赞赏,在此先感谢。

标签: rubynet-http

解决方案


推荐阅读