4

Current code works as long as there is no remote error:

def get_name_from_remote_url
      cstr = "http://someurl.com"
      getresult = open(cstr, "UserAgent" => "Ruby-OpenURI").read
      doc = Nokogiri::XML(getresult)
      my_data = doc.xpath("/session/name").text
      #  => 'Fred' or 'Sam' etc
      return my_data
end

But, what if the remote URL times out or returns nothing? How I detect that and return nil, for example?

And, does Open-URI give a way to define how long to wait before giving up? This method is called while a user is waiting for a response, so how do we set a max timeoput time before we give up and tell the user "sorry the remote server we tried to access is not available right now"?

4

1 回答 1

9

Open-URI 很方便,但这种易用性意味着他们正在删除对 Net::HTTP 等其他 HTTP 客户端允许的许多配置细节的访问。

这取决于您使用的 Ruby 版本。对于 1.8.7,您可以使用Timeout模块。从文档:

require 'timeout'
begin
status = Timeout::timeout(5) {
  getresult = open(cstr, "UserAgent" => "Ruby-OpenURI").read
}
rescue Timeout::Error => e
  puts e.to_s
end

然后检查getresult的长度,看看有没有内容:

if (getresult.empty?)
  puts "got nothing from url"
end

如果您使用的是 Ruby 1.9.2,您可以在:read_timeout => 10该方法中添加一个选项open()


此外,您的代码可以收紧并变得更加灵活。这将允许您传入一个 URL 或默认为当前使用的 URL。另请阅读 Nokogiri 的NodeSetxpath文档以了解,和, , /,之间的区别:cssat%at_cssat_xpath

def get_name_from_remote_url(cstr = 'http://someurl.com')
  doc = Nokogiri::XML(open(cstr, 'UserAgent' => 'Ruby-OpenURI'))

  # xpath returns a nodeset which has to be iterated over
  # my_data = doc.xpath('/session/name').text #  => 'Fred' or 'Sam' etc  

  # at returns a single node
  doc.at('/session/name').text
end
于 2011-02-11T06:30:57.027 回答