Использование Open-URI для извлечения XML и передовой опыт в случае проблем с удаленным URL-адресом, который не возвращается/не истекает?

Текущий код работает до тех пор, пока нет удаленной ошибки:

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

Но что, если удаленный URL-адрес истечет или ничего не вернет? Как я могу обнаружить это и вернуть nil, например?

И дает ли Open-URI способ определить, как долго ждать, прежде чем сдаться? Этот метод вызывается, когда пользователь ожидает ответа, так как же нам установить максимальное время вывода, прежде чем мы сдадимся и скажем пользователю: «Извините, удаленный сервер, к которому мы пытались получить доступ, сейчас недоступен»?


person jpw    schedule 10.02.2011    source источник


Ответы (1)


Open-URI удобен, но эта простота использования означает, что они удаляют доступ ко многим деталям конфигурации, которые разрешают другие HTTP-клиенты, такие как Net::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 NodeSet, чтобы понять разницу между xpath, /, css и at, %, at_css, at_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
person the Tin Man    schedule 11.02.2011