2011-09-15 10 views
9

Ho una funzione di meccanizzazione per disconnettermi da un sito ma in rare occasioni mi fa perdere tempo. La funzione implica andare a una pagina specifica e quindi fare clic su un pulsante di disconnessione. Occasionalmente che mechanize subisce un timeout quando si va alla pagina di disconnessione o si fa clic sul pulsante di disconnessione il codice si arresta in modo anomalo. Così ho messo un piccolo salvataggio e sembra che funzioni come visto sotto il primo pezzo di codice.Errori di timeout di cattura con ruby ​​mechanize

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

Logmeout con salvataggio:

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 

Supponendo ho capito bene di soccorso, lo farà entrambe le azioni sopra anche se solo il ticchettio scaduta, così nello sforzo di essere efficiente Mi chiedevo se Potrei usare un proc in questa situazione e passargli un blocco di codice. Sarebbe qualcosa di simile a questo lavoro:

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 nella mia funzione trythreetimes ho lasciato come soccorso generico in modo la funzione sarebbe più riutilizzabili.

Grazie mille per l'aiuto che chiunque può fornire, mi rendo conto che ci sono un paio di domande diverse qui ma sono tutte cose che sto cercando di imparare!

risposta

9

Invece di riprovare alcuni timeout su alcune richieste di meccanizzazione, penso che sarebbe meglio impostare l'attributo Mechanize::HTTP::Agent::read_timeout su un numero ragionevole di secondi come 2 o 5, ad ogni modo uno che prevenga errori di timeout per questa richiesta.

Quindi, sembra che la procedura di disconnessione richiedesse solo l'accesso a una semplice richiesta HTTP GET. Voglio dire, non esiste un modulo da compilare, quindi nessuna richiesta HTTP POST. Quindi, se fossi in te, preferirei ispezionare il codice sorgente della pagina (Ctrl + U con Firefox o Chrome) per identificare il collegamento che viene raggiunto dal tuo agent.click(page.link_with(:text => /Log Out/i)) Dovrebbe essere più veloce perché questi tipi di pagine sono di solito vuoti e Mechanize non dovrà caricare una pagina Web completa in html in memoria.

ecco il codice io preferirei 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 

ma è possibile utilizzare la funzione di tentativi troppo:

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 

Speranza che aiuta! ;-)

+0

Grazie per la risposta! Il tuo codice preferito presuppone che tu abbia trovato il link corretto attraverso il codice sorgente? – Sean

+0

Beh, non è molto difficile trovare un collegamento all'interno di una fonte HTML. Preferisco questa soluzione a causa del tempo e della memoria necessari. ma puoi usare la tua soluzione con il set ['read_timeout'] (http://mechanize.rubyforge.org/Mechanize/HTTP/Agent.html#read_timeout=). È una buona idea se lo usi per più domini. Modifica il mio secondo codice di sicurezza e modificalo per accedere alla pagina principale e fare clic sul link, se preferisci. – cz3ch

+0

Oh scusa, non ho risposto alla tua domanda in effetti. Sì, supponiamo che tu abbia trovato il link corretto attraverso il codice sorgente ... – cz3ch

0

Utilizzo di mechanize 1.0.0 Ho riscontrato questo problema da una diversa fonte di errore.

Nel mio caso sono stato bloccato da proxy e quindi SSL. Questo ha funzionato per me:

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