1

下面是我用来获取网页 HTML 内容的 Ruby 代码。我不允许更改此代码。

def getHtmlFromUrl(url)
    uri = URI.parse(url)
    http = Net::HTTP.new(uri.host, uri.port)
    http.read_timeout = 2
    html = http.get(uri.to_s)
    # ...
    # Handle any error that may have occurred (return nil)
    # ...
    return html.body
end

此代码似乎在读取某些没有尾部斜杠的 URL 时出现问题。例如,当我尝试读取时出现错误http://drive.google.com,但没有http://drive.google.com/。为什么会这样?我决定实施一个修复,如果没有指定路径,我会在域中添加一个斜杠。这是一个安全的解决方法吗?是否有可能在 的情况下发生错误http://somedomain.com/并正常工作http://somedomain.com

4

2 回答 2

0

始终使用斜杠应该不会有任何问题,但另一种选择是遵循重定向(drive.google.com 可能会将您重定向到 drive.google.com/ )。

有关如何使用 Net:HTTP 处理重定向的更多信息,请参阅此答案(和评论):https ://stackoverflow.com/a/6934503/1691

于 2013-12-08T03:14:26.190 回答
0

听起来问题确实是因为您没有处理重定向。Net::HTTP 文档包含有关处理它们的信息。这是一个非常简单的过程:

跟随重定向

每个 Net::HTTPResponse 对象都属于其响应代码的一个类。

例如,所有 2XX 响应都是 Net::HTTPSuccess 子类的实例,3XX 响应是 Net::HTTPRedirection 子类的实例,而 200 响应是 Net::HTTPOK 类的实例。有关响应类的详细信息,请参阅下面的“HTTP 响应类”部分。

使用 case 语句,您可以正确处理各种类型的响应:

def fetch(uri_str, limit = 10)
  # 你应该选择一个更好的例外。
  引发 ArgumentError, 'too many HTTP redirects' if limit == 0

  response = Net::HTTP.get_response(URI(uri_str))

  个案回应
  当 Net::HTTPS 成功时
    回复
  当 Net::HTTPRedirection 然后
    位置=响应['位置']
    警告“重定向到 #{location}”
    获取(位置,限制 - 1)
  别的
    响应值
  结尾
结尾

print fetch('http://www.ruby-lang.org')

也就是说,有许多用于 Ruby 的 HTTP 客户端可以帮助您处理这种情况,因为它很常见,因此您可以专注于更重要的事情,例如处理丢失的页面、超时、并行处理/处理多个请求、解码 JSON /XML/YAML。我建议查看这些(无特定顺序)并查看它们提供的内容:

  • 台风Typhoeus.get("www.example.com", followlocation: true)
  • HTTP客户端puts clnt.get('http://dev.ctor.org/', :follow_redirect => true)
  • 路边

    follow_location = boolean → boolean
    

    配置此 Curl 实例是否将遵循Location:HTTP 响应中的标头。重定向将仅在 指定的范围内进行max_redirects

  • HTTP派对

    当 HTTP 响应指示重定向时,继续到位置标头。默认情况下始终遵循重定向。

    例子:

    class Foo
      include HTTParty
      base_uri 'http://google.com'
      follow_redirects true
    end
    
于 2013-12-08T04:52:01.183 回答