使用ruby mechanize捕获超时错误

我有一个机械化function可以让我退出网站,但在非常罕见的情况下它会让我失望。 该function涉及转到特定页面,然后单击注销按钮。 偶尔机械化在进入注销页面或单击注销按钮时会出现超时,代码崩溃。 所以我进行了一次小规模的救援,它似乎正如第一段代码所示。

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

Logmeout with rescue:

 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 

假设我正确地理解了救援,即使只是点击超时,它也会做两个动作,所以为了提高效率,我想知道我是否可以在这种情况下使用proc并将其传递给代码块。 会这样的工作:

 def trythreetimes tries = 0 begin yield rescue tries += 1 puts "Trying again!" retry if tries  /Log Out/i))} end 

请注意,在我的trythreetimes函数中,我将其保留为通用救援,因此该function将更加可重用。

非常感谢任何人提供的任何帮助,我知道这里有几个不同的问题,但它们都是我想要学习的东西!

我认为你最好将Mechanize::HTTP::Agent::read_timeout属性设置为合理的秒数,如2或5,而不是重试某些机械化请求的超时,无论如何都要阻止此请求的超时错误。

然后,似乎您的注销过程只需要访问简单的HTTP GET请求。 我的意思是没有表格可以填写,所以没有HTTP POST请求。 所以,如果我是你,我会优先检查页面源代码(使用Firefox或Chrome的Ctrl + U)以识别您的agent.click(page.link_with(:text => /Log Out/i))所达到的链接agent.click(page.link_with(:text => /Log Out/i))它应该更快,因为这些类型的页面通常是空白的,而Mechanize不必在内存中加载完整的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 

但你也可以使用你的重试function:

 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 

希望能帮助到你 ! 😉

使用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 )