2011-09-15 34 views
9

Tôi có chức năng cơ giới hóa để đăng xuất tôi khỏi một trang web nhưng trong những dịp rất hiếm khi xảy ra với tôi. Chức năng liên quan đến việc đi đến một trang cụ thể, và sau đó nhấp vào nút đăng xuất. Đôi khi, cơ giới hóa bị hết thời gian chờ khi truy cập trang đăng xuất hoặc nhấp vào nút đăng xuất mà mã bị treo. Vì vậy, tôi đặt trong một cứu hộ nhỏ và nó có vẻ là làm việc như được thấy bên dưới đoạn mã đầu tiên.Gặp lỗi hết thời gian với cơ chế ruby ​​

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

Logmeout với cứu hộ:

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 

Giả sử tôi hiểu giải cứu một cách chính xác, nó sẽ làm cả hai hành động trên ngay cả khi chỉ việc nhấp chuột timed out, vì vậy trong các nỗ lực để có hiệu quả tôi đã tự hỏi nếu Tôi có thể sử dụng một proc trong tình huống này và vượt qua nó một khối mã. Có điều gì đó tương tự như công việc này:

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 

Lưu ý trong chức năng trythreetimes của tôi, tôi để nó là giải pháp chung để chức năng có thể sử dụng lại được.

Cảm ơn rất nhiều sự giúp đỡ mà bất kỳ ai có thể cung cấp, tôi nhận thấy có một vài câu hỏi khác nhau ở đây nhưng tất cả đều là những thứ tôi đang cố gắng học!

Trả lời

9

Thay vì thử lại một số thời gian chờ trên một số yêu cầu cơ học, tôi nghĩ bạn nên đặt thuộc tính Mechanize::HTTP::Agent::read_timeout thành số giây hợp lý như 2 hoặc 5, dù là thời gian chờ lỗi cho yêu cầu này.

Sau đó, có vẻ như quy trình đăng xuất của bạn chỉ yêu cầu quyền truy cập vào yêu cầu HTTP GET đơn giản. Tôi có nghĩa là không có hình thức để điền vào để không có yêu cầu HTTP POST. Vì vậy, nếu tôi là bạn, tôi sẽ kiểm tra trước mã nguồn trang (Ctrl + U bằng Firefox hoặc Chrome) để xác định liên kết được truy cập bởi agent.click(page.link_with(:text => /Log Out/i)) Nó sẽ nhanh hơn vì các loại trang này thường trống và Cơ chế sẽ không phải tải một trang web html đầy đủ trong bộ nhớ.

Đây là mã tôi muốn sử dụng:

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 

nhưng bạn có thể sử dụng chức năng retry của bạn quá:

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 

hy vọng nó sẽ giúp! ;-)

+0

Cảm ơn bạn đã trả lời! Mã ưa thích của bạn là giả sử bạn tìm thấy liên kết chính xác thông qua mã nguồn? – Sean

+0

Thật không khó để tìm một liên kết bên trong nguồn HTML. Tôi thích giải pháp này vì thời gian và bộ nhớ cần thiết. nhưng bạn có thể sử dụng giải pháp của mình với ['read_timeout'] (http://mechanize.rubyforge.org/Mechanize/HTTP/Agent.html#read_timeout=). Đó là một ý tưởng tốt nếu bạn sử dụng nó cho nhiều tên miền. Chỉ cần chỉnh sửa mã hòa bình thứ hai của tôi và thay đổi nó để truy cập trang chính và nhấp vào liên kết nếu bạn thích. – cz3ch

+0

Xin lỗi, tôi đã không trả lời câu hỏi của bạn trên thực tế. Có, giả sử bạn tìm thấy liên kết chính xác thông qua mã nguồn ... – cz3ch

0

Sử dụng cơ giới hóa 1.0.0 Tôi gặp vấn đề này từ một nguồn lỗi khác.

Trong trường hợp của tôi, tôi đã bị chặn bởi proxy và sau đó là SSL. Điều này làm việc cho tôi:

ag = Mechanize.new 
ag.set_proxy('yourproxy', yourport) 
ag.agent.http.verify_mode = OpenSSL::SSL::VERIFY_NONE 
ag.get(url) 
Các vấn đề liên quan