2011-09-15 14 views
9

Tengo una función de mecanizar para desconectarme de un sitio pero en muy raras ocasiones me interrumpe. La función implica ir a una página específica y luego hacer clic en un botón de cerrar sesión. De vez en cuando Mechanize sufre un tiempo de espera cuando, al ir a la página de cierre de sesión o al hacer clic en el botón de cerrar sesión, el código falla. Así que hice un pequeño rescate y parece estar funcionando como se ve debajo del primer código.Captura de errores de tiempo de espera con mecanizado de ruby ​​

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

Logmeout con rescate:

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 

Suponiendo que entiendo rescate correctamente, lo hará ambas acciones más aunque sólo el clic Tiempo de espera agotado, por lo que en el esfuerzo para ser eficiente estoy preguntaba si Podría usar un proceso en esta situación y pasarle un bloque de código. Sería algo así como este trabajo:

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 

nota en mi función trythreetimes me dejaron como rescate genérica lo que la función sería más reutilizable.

Muchas gracias por cualquier ayuda que alguien pueda brindarme, me doy cuenta de que hay un par de preguntas diferentes aquí, pero son todas las cosas que trato de aprender.

Respuesta

9

En lugar de intentar algunos tiempos de espera en algunas solicitudes de mecanizado, creo que será mejor que establezca el atributo Mechanize::HTTP::Agent::read_timeout en una cantidad razonable de segundos como 2 o 5, de todos modos uno que evite los errores de tiempo de espera para esta solicitud.

Luego, parece que su procedimiento de cierre de sesión solo requería acceso a una simple solicitud HTTP GET. Quiero decir que no hay ningún formulario para completar, así que no hay una solicitud HTTP POST. Así que si yo fuera usted, preferiría inspeccionar el código fuente de la página (Ctrl + U con Firefox o Chrome) para identificar el enlace al que llega su agent.click(page.link_with(:text => /Log Out/i)) Debería ser más rápido porque este tipo de páginas suelen estar en blanco y Mechanize no tendrá que cargar una página web html completa en la memoria.

Aquí está el código que preferiría uso:

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 

pero puede utilizar su función de reintento demasiado:

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 

espero que ayude! ;-)

+0

¡Gracias por la respuesta! ¿Su código preferido es asumir que encontró el enlace correcto a través del código fuente? – Sean

+0

Bueno, no es realmente difícil encontrar un enlace dentro de una fuente HTML. Prefiero esta solución debido al tiempo y la memoria necesarios. pero puede usar su solución con el conjunto ['read_timeout'] (http://mechanize.rubyforge.org/Mechanize/HTTP/Agent.html#read_timeout=). Es una buena idea si lo usa para múltiples dominios. Solo edite mi segunda pausa de código y cámbiela para acceder a la página principal y haga clic en el enlace si lo prefiere. – cz3ch

+0

Oh, lo siento, de hecho, no respondí tu pregunta. Sí, es asumiendo que encontraste el enlace correcto a través del código fuente ... – cz3ch

0

Usando mechanize 1.0.0 Obtuve este problema de una fuente de error diferente.

En mi caso, me bloquearon el proxy y luego SSL. Esto funcionó para mí:

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