【发布时间】:2014-04-15 23:53:01
【问题描述】:
我正在使用 Selenium 和 Python 来测试网络应用程序;但是,Firefox 会定期进入“无响应”状态。当 Firefox 处于这种状态时,脚本会挂起,直到我关闭它。
我试过了:
br = webdriver.Firefox()
br.set_page_load_timeout(10)
和
br = webdriver.Firefox()
br.implicitly_wait(10)
我担心我的问题无法通过wait 或timeout 方法解决,因为该页面是Ajax。 .click() 或 .submit() 方法发送 POST 来回答问题,响应是字典,它通过 JavaScript 用新问题更新页面。 (这是我在谷歌Chrome开发者工具Ctrl+Shift+I中使用Network选项卡的理解)
问题是:
如何在 Selenium 中捕获 Firefox 无响应的情况?
我希望捕捉到这种情况,这样我就可以关闭浏览器并启动一个新浏览器。
在ExperimentsWithCode 的回答之后编辑:
这是我的代码的 sn-p 来说明我的问题。
def answer_questions(self):
q = QuestionParser(self.br.page_source)
q.add_to_db()
qid = q.get_qid()
# My answer
my_answer_id = q.get_my_answer()
self.br.find_element_by_id(my_answer_id).click()
# Submit answer
self.br.find_element_by_xpath('//*[contains(@id, "submit_btn_")]').click()
try:
find_id = "submit_btn_" + str(qid)
element = WebDriverWait(self.br,10).until(EC.presence_of_element_located((By.ID, find_id)))
except:
print 'I caught you'
self.rnd(mu=7, s=2) # a method to sleep for a random time
我在循环中调用answer_questions() 方法。这段代码运行良好,直到 Firefox 崩溃,然后它会挂起,直到我关闭它。我read the docs 并担心我已经用尽了一切。问题是没有加载页面或元素。 问题是我不知道如何检测 Firefox 何时崩溃。 WebDriverWait 看起来很有希望,但当 Firefox 崩溃时它没有抛出 TimeoutException。
感谢您的宝贵时间。
我想出了一个补救办法来解决我的问题。这是我所做的一个 sn-p:
import os, socket
from threading import Timer
def force_timeout(self):
os.system('taskkill /im firefox.exe /f /t')
# for Windows
# /im firefox.exe is to select firefox
# /f is to forcefully kill
# /t is to kill all child processes
for i in range(0, 1000):
try:
t = Timer(60, self.force_timeout)
# run force_timeout from new thread after 60 seconds
t.start() # start timer
self.answer_questions()
# if self.answer_questions() finishes before 60s, cancel timer
t.cancel() # cancel timer
except socket.error:
self.new_browser() # create a new browser
self.login() # login
self.go_to_questions() # Go to questions page so the loop can continue
# Code to recover from crash here
如果answer_questions() 方法未在 60 秒内完成,force_timeout() 将从新线程运行并强制终止 firefox.exe。一旦 Firefox 终止,代码将抛出 socket.error 错误。抓住这个错误,然后做你需要做的事情来从浏览器崩溃中恢复。我发现代码有点脏,但它完全按照我的需要工作。
供将来参考:操作系统 - Win8,Selenium 版本 - 2.40.0,Firefox 版本 - 27.0.1
【问题讨论】:
-
问题是当页面没有完全加载浏览器或者你的代码正在等待响应。
-
@Vkt0rS。这不是我的情况。我的字面意思是 Firefox 没有响应,即我必须进入任务管理器才能强行杀死 Firefox。我用我用来解决问题的补救措施更新了我的问题,因为我得出结论 Selenium 无法处理处于无响应状态的浏览器。
-
非常好的补救措施!谢谢。不过,您可以将其发布为答案。
-
您不需要在
except socket.error分支中说t.cancel()吗?否则,即使您尝试重新启动它,您的计时器也可能会杀死 firefox。 -
@max
t.cancel()必须尝试。如果 Firefox 停止响应,计时器将达到 60 秒并杀死 FireFox。如果 FireFox 没有崩溃,我们必须取消计时器,即t.cancel()。如果计时器达到 60 秒,force_timeout方法将执行并杀死 FireFox,并抛出socket.error错误。