【问题标题】:Ruby parsing HTTPresponse with NokogiriRuby 使用 Nokogiri 解析 HTTPresponse
【发布时间】:2012-07-05 21:14:58
【问题描述】:

使用 Nokogiri 解析 HTTP 响应

您好,我在使用 Nokogiri 解析 HTTPresponse 对象时遇到问题。

我在这里使用这个函数来获取一个网站:

获取链接

def fetch(uri_str, limit = 10)
   
  
  # You should choose better exception.
  raise ArgumentError, 'HTTP redirect too deep' if limit == 0
  
  url = URI.parse(URI.encode(uri_str.strip))
  puts url
  
  #get path
  req = Net::HTTP::Get.new(url.path,headers)
  #start TCP/IP
  response = Net::HTTP.start(url.host,url.port) { |http|
        http.request(req)
  }
  case response
  when Net::HTTPSuccess
    then #print final redirect to a file
    puts "this is location" + uri_str
    puts "this is the host #{url.host}"
    puts "this is the path #{url.path}"
    
    return response
    # if you get a 302 response
  when Net::HTTPRedirection 
    then 
    puts "this is redirect" + response['location']
    return fetch(response['location'],aFile, limit - 1)
  else
    response.error!
  end
end




            html = fetch("http://www.somewebsite.com/hahaha/")
            puts html
            noko = Nokogiri::HTML(html)
            

当我这样做时,html 会打印出一大堆乱码和 Nokogiri 抱怨“node_set 必须是 Nokogiri::XML::NOdeset

如果有人能提供帮助将不胜感激

【问题讨论】:

  • 你应该使用机械化而不是这个热的烂摊子。它负责重定向并为您处理编码。

标签: ruby nokogiri


【解决方案1】:

第一件事。您的 fetch 方法返回一个 Net::HTTPResponse 对象,而不仅仅是正文。您应该将尸体提供给 Nokogiri。

response = fetch("http://www.somewebsite.com/hahaha/")
puts response.body
noko = Nokogiri::HTML(response.body)

我已经更新了您的脚本,使其可以运行(如下所示)。有几件事是未定义的。

require 'nokogiri'
require 'net/http'

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

  url = URI.parse(URI.encode(uri_str.strip))
  puts url

  #get path
  headers = {}
  req = Net::HTTP::Get.new(url.path,headers)
  #start TCP/IP
  response = Net::HTTP.start(url.host,url.port) { |http|
        http.request(req)
  }

  case response
  when Net::HTTPSuccess
    then #print final redirect to a file
    puts "this is location" + uri_str
    puts "this is the host #{url.host}"
    puts "this is the path #{url.path}"

    return response
    # if you get a 302 response
  when Net::HTTPRedirection
    then
    puts "this is redirect" + response['location']
    return fetch(response['location'], limit-1)
  else
    response.error!
  end
end

response = fetch("http://www.google.com/")
puts response
noko = Nokogiri::HTML(response.body)
puts noko

脚本没有错误并打印内容。由于您收到的内容,您可能会收到 Nokogiri 错误。我在使用 Nokogiri 时遇到的一个常见问题是字符编码。如果没有确切的错误,就不可能知道发生了什么。

我建议查看以下 StackOverflow 问题

ruby 1.9: invalid byte sequence in UTF-8(特别是this answer

How to convert a Net::HTTP response to a certain encoding in Ruby 1.9.1?

【讨论】:

  • 非常感谢 Simard 先生,我会查一下字符编码。
  • 如何查看更详细的调试消息? Nokogiri 给我的唯一错误是这个 node_set 必须是 Nokogiri::XML::Nodeset
  • 好的,我做了 script.rb -d 这是输出:YPscraper.rb:103: warning: (...) 解释为分组表达式 script.rb:118: warning: mismatched indentations在 'end' 和 'begin' 在 87 YPscraper.rb:119:警告:在 83 处的 'end' 与 'for' 的缩进不匹配 Exception LoadError' at C:/Ruby193/lib/ruby/site_ruby/1.9.1/rubygems/custom_req uire.rb:36 - cannot load such file -- nokogiriException ArgumentError' at script.rb:102 - node_set 必须是 Nokogiri:: XML ::NodeSet node_set 必须是 Nokogiri::XML::NodeSet
  • Nokogiri 似乎真的不喜欢您收到的内容。我建议将其保存到文件中并进行检查。
  • 嗨,Pierre-Luc,我昨天已经解决了这个问题,基本上我做了这样的事情:page = Nokogiri::HTML(response.body) page.xpath("//div[(position ()=1 and @class='listing_content')]/div/div/h3/a/text()") puts "this is name" puts name #Get Business phone phone = page.xpath("//div[ @class='listing_content']//span[@class='business-phone phone']/text()") puts "this is phone" puts phone aFile.syswrite(noko + " " + phone) 显然 syswrite 没有'不喜欢连接的尝试感谢您的帮助。如果您有更多的 cmets,总是欢迎。
猜你喜欢
  • 2014-09-15
  • 1970-01-01
  • 1970-01-01
  • 2021-02-19
  • 2013-01-05
  • 1970-01-01
  • 2021-01-20
  • 1970-01-01
  • 2018-05-03
相关资源
最近更新 更多