Перехват ошибок тайм-аута с помощью Ruby Mechanize - PullRequest
9 голосов
/ 15 сентября 2011

У меня есть функция механизации, чтобы выйти из сайта, но в очень редких случаях это делает меня тайм-аутом. Функция включает в себя переход на определенную страницу, а затем нажмите кнопку выхода из системы. Иногда, когда механизация страдает от тайм-аута, либо при переходе на страницу выхода из системы, либо при нажатии кнопки выхода из системы происходит сбой кода. Поэтому я добавил небольшое спасение, и оно работает, как видно из первого фрагмента кода.

def logmeout(agent)
  page = agent.get('http://www.example.com/')
  agent.click(page.link_with(:text => /Log Out/i))
end      

Выход из системы со спасением:

def logmeout(agent)
  begin
  page = agent.get('http://www.example.com/')
  agent.click(page.link_with(:text => /Log Out/i))
  rescue Timeout::Error 
    puts "Timeout!"
    retry
  end
end

Предполагая, что я правильно понимаю спасение, оно выполнит оба действия, даже если просто щелкнет тайм-аут, поэтому в стремлении быть эффективным, мне было интересно, смогу ли я использовать прок в этой ситуации и передать ему блок кода. Будет ли что-то вроде этой работы:

def trythreetimes
  tries = 0
  begin
  yield
  rescue
    tries += 1
    puts "Trying again!"
    retry if tries <= 3
  end
end

def logmeout(agent)
  trythreetimes {page = agent.get('http://www.example.com/')}
  trythreetimes {agent.click(page.link_with(:text => /Log Out/i))}
end

Заметьте, в моей функции trythreetimes я оставил ее как общее спасение, чтобы эта функция была более пригодной для повторного использования.

Большое спасибо за любую помощь, которую кто-либо может оказать, я понимаю, что здесь есть пара разных вопросов, но это все, чему я пытаюсь научиться!

Ответы [ 2 ]

9 голосов
/ 15 сентября 2011

Вместо повторения некоторых тайм-аутов для некоторых запросов механизации, я думаю, вам лучше установить атрибут Mechanize::HTTP::Agent::read_timeout на разумное количество секунд, например 2 или 5, в любом случае, то, которое предотвращает ошибки тайм-аутов для этого запроса.

Тогда, похоже, ваша процедура выхода из системы требовала доступа только к простому HTTP-запросу GET.Я имею в виду, что нет формы для заполнения, поэтому нет запроса HTTP POST.Так что на вашем месте я бы предпочел проверить исходный код страницы (Ctrl + U с Firefox или Chrome), чтобы определить ссылку, которая достигается вашим agent.click(page.link_with(:text => /Log Out/i)). Это должно быть быстрее, потому что страницы такого типа обычно пустые иМеханизму не нужно загружать в память полную html-страницу.

Вот код, который я бы предпочел использовать:

def logmeout(agent)
  begin
  agent.read_timeout=2  #set the agent time out
  page = agent.get('http://www.example.com/logout_url.php')
  agent.history.pop()   #delete this request in the history
  rescue Timeout::Error 
    puts "Timeout!"
    puts "read_timeout attribute is set to #{agent.read_timeout}s" if !agent.read_timeout.nil?
    #retry      #retry is no more needed
  end
end

, но вы также можете использовать свою функцию повтора:

def trythreetimes
  tries = 0
  begin
  yield
  rescue Exception => e  
  tries += 1
  puts "Error: #{e.message}"
  puts "Trying again!" if tries <= 3
  retry if tries <= 3
  puts "No more attempt!"
  end
end

def logmeout(agent)
  trythreetimes do
  agent.read_timeout=2  #set the agent time out
  page = agent.get('http://www.example.com/logout_url.php')
  agent.history.pop()       #delete this request in the history
  end
end

надеюсь, это поможет!; -)

0 голосов
/ 28 января 2015

Используя mechanize 1.0.0, я получил эту проблему из другого источника ошибки.

В моем случае я был заблокирован прокси, а затем SSL.Это сработало для меня:

ag = Mechanize.new
ag.set_proxy('yourproxy', yourport)
ag.agent.http.verify_mode = OpenSSL::SSL::VERIFY_NONE
ag.get( url )
...