2011-09-15 13 views
9

Mam funkcję mechanizacji, która wylogowuje mnie z witryny, ale w bardzo rzadkich przypadkach pomija mnie. Funkcja obejmuje przechodzenie do określonej strony, a następnie kliknięcie przycisku wylogowania. Od czasu do czasu, gdy mechanize cierpi z powodu przekroczenia limitu czasu, kiedy następuje przejście do strony wylogowania lub kliknięcie przycisku wylogowania, kod ulega awarii. Więc wprowadziłem małą akcję ratunkową i wygląda na to, że działa jak widać poniżej pierwszego fragmentu kodu.Błędy przekroczenia limitu czasu przy mechanizmie ruby ​​

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

Logmeout z ratownictwa:

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 

Zakładając Rozumiem ratowanie poprawnie, będzie to robić zarówno działania na nawet jeśli tylko kliknięcie limit czasu, więc w wysiłkach, aby być skuteczne ja zastanawiałem się, czy Mógłbym użyć proc w tej sytuacji i przekazać mu blok kodu. Czy coś w tej pracy:

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 

Uwaga w mojej funkcji trythreetimes Zostawiłem go jako rodzajowy ratunek więc funkcja będzie bardziej wielokrotnego użytku.

Dziękuję bardzo za pomoc, którą każdy może zapewnić, zdaję sobie sprawę, że tutaj jest kilka różnych pytań, ale wszystkie są tym, czego próbuję się nauczyć!

Odpowiedz

9

Zamiast ponawiania niektórych limitów czasu na niektóre żądania zmechanizowania, myślę, że lepiej ustawić atrybut Mechanize::HTTP::Agent::read_timeout na uzasadnioną liczbę sekund, np. 2 lub 5, w każdym razie jeden, który zapobiega błędom limitu czasu dla tego żądania.

Wydaje się, że procedura wylogowania wymagała jedynie dostępu do prostego żądania HTTP GET. Chodzi mi o to, że nie ma formy do wypełnienia, więc nie ma żądania HTTP POST. Więc jeśli byłbym tobą, wolałbym sprawdzić kod źródłowy strony (Ctrl + U w przeglądarce Firefox lub Chrome), aby zidentyfikować link, który jest osiągany przez Twój agent.click(page.link_with(:text => /Log Out/i)) Powinien być szybszy, ponieważ tego typu strony są zwykle puste i Mechanize nie będzie musiał ładować pełnej strony HTML w pamięci.

Oto kod wolałbym użyć:

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 

ale można użyć funkcji ponawiania też:

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 

nadzieję, że to pomaga! ;-)

+0

Dzięki za odpowiedź! Twój preferowany kod zakłada, że ​​znalazłeś poprawny link przez kod źródłowy? – Sean

+0

Cóż, nie jest trudno znaleźć link wewnątrz źródła HTML. Preferuję to rozwiązanie ze względu na potrzebny czas i pamięć. ale możesz użyć swojego rozwiązania za pomocą zestawu ['read_timeout'] (http://mechanize.rubyforge.org/Mechanize/HTTP/Agent.html#read_timeout=). To dobry pomysł, jeśli używasz go do wielu domen. Po prostu edytuj mój drugi spokój kodu i zmień go, aby uzyskać dostęp do strony głównej i kliknij link, jeśli wolisz. – cz3ch

+0

O, przykro mi, nie odpowiedziałem na twoje pytanie w rzeczywistości. Tak, zakładam, że znalazłeś poprawny link przez kod źródłowy ... – cz3ch

0

Korzystanie z mechanizmu 1.0.0 Mam ten problem z innego źródła błędu.

W moim przypadku zostałem zablokowany przez serwer proxy, a następnie SSL. To zadziałało dla mnie:

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