【问题标题】:Check if Nokogiri HTML document is usable检查 Nokogiri HTML 文档是否可用
【发布时间】:2013-01-14 20:44:29
【问题描述】:

我想检查用户输入的 URL 是否真的是一个有效的页面。

我试过了:

if Nokogiri::HTML(open("http://example.com"))
  #DO REQUIRED TASK
end

但这会在尝试打开页面时立即引发错误。我想返回它是否是任何类型的文档的结果。

我要么得到错误:

no such file or directory

或:

getaddrinfo: Name or service not known

取决于我如何进行检查。

【问题讨论】:

  • 如果有人将 URL 传递给图像或多 GB 文件怎么办?您的代码将无法处理 Nokogiri 爆炸或无意中对您的主机进行 DOS 操作,因为它耗尽了 RAM。在请求 Nokogiri 解析之前,您需要处理异常并尝试嗅探 URL 以确定要返回的内容。

标签: ruby-on-rails ruby screen-scraping nokogiri


【解决方案1】:

我会从以下内容开始:

require 'nokogiri'
require 'open-uri'

begin
  doc = Nokogiri.HTML(open(url))
rescue Exception => e
  puts "Couldn't read \"#{ url }\": #{ e }"
  exit
end

puts (doc.errors.empty?) ? "No problems found" : doc.errors

Nokogiri 将文档的 errors 数组设置为解析过程中发生的任何错误的值。

不过,这只解决了问题的一部分。恶意的人喜欢破坏东西,这很容易破坏。一般来说,对用户提供给您的任何东西都要非常小心,尤其是当您的网站暴露在狂野的互联网上时。

在告诉 OpenURI 加载文件以提供给 Nokogiri 之前,您应该嗅探该 URL 并使用 HTTP HEAD 请求进行一些完整性检查,以找出正在检索的内容的大小和 MIME-TYPE。知道这些后,您可以尝试加载文件。

【讨论】:

  • 我实际上是在你发帖之前就想到了这个。这确实是正确的想法。
【解决方案2】:

首先,在 Ruby 中 'rescue Exception => e' 是不好的风格。 [参考:http://daniel.fone.net.nz/blog/2013/05/28/why-you-should-never-rescue-exception-in-ruby/]

其次,对于这种情况,“rescue OpenURI::HTTPError => e”会更合适。

【讨论】:

    【解决方案3】:

    我不熟悉处理异常,但类似:

    begin
      page = Nokogiri::HTML(open("http://example.com"))
    ensure
      puts "not a document of any kind"
    end
    do_something_whith(page) if page
    

    ...应该可以解决问题。

    或(阅读您的评论后):

    begin
      page = open("http://example.com")
    ensure
      puts "not a document of any kind"
    end
    Nokogiri::HTML(page) if page
    

    【讨论】:

    • 我在打开点得到相同的 getaddrinfo: Name or service not known 异常。这就像程序偷看,然后无论如何都会在这一点上被咬掉。
    • 同样的交易。似乎 open-uri 是这里的大问题。
    • 我不得不给另一个人打勾,但谢谢你让我朝着正确的方向前进。
    猜你喜欢
    • 2016-10-31
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    • 2012-08-06
    • 2012-07-02
    • 2019-01-08
    • 2012-01-08
    • 1970-01-01
    相关资源
    最近更新 更多