在 Python 中使用 Selenium WebDriver 时处理 Firefox 无响应?
Posted
技术标签:
【中文标题】在 Python 中使用 Selenium WebDriver 时处理 Firefox 无响应?【英文标题】:Handle Firefox Not Responding While Using Selenium WebDriver With Python? 【发布时间】: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
Windows Taskkill Python threading.Timer
【问题讨论】:
问题是当页面没有完全加载浏览器或者你的代码正在等待响应。 @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
错误。
【参考方案1】:
对于那些使用 *nix 的人,
os.system("pkill -P %d firefox" % os.getpid())
可以很好地杀死当前进程的 Firefox 子进程。
pkill man page
【讨论】:
【参考方案2】:Webdriver 文档有一个关于 here 之类的部分。
从文档中,您可以尝试显式等待:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
br = webdriver.Firefox()
br.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(br, 10).until(EC.presence_of_element_located((By.ID, "_element_You_Are_Need_To_Load")))
finally:
br.quit()
如果在 10 秒内找不到元素,这将超时,或者返回该窗口内的元素。
【讨论】:
谢谢,我试过你的建议;但是,当 Firefox 崩溃时,它并没有抛出TimeoutException
。脚本只是闲置,直到我关闭它。我更新了我的问题以反映这一点。
有没有可能元素已经加载而页面的其余部分没有?您可以尝试让它搜索该页面上不存在的 ID 并查看它是否收到 TimeoutException?
是的,我尝试搜索不存在的 ID,例如在我的问题的代码中,我这样做了:find_id = "1submit_btn_" + str(qid)
提交前面的额外1
不存在。代码按预期抛出错误。我的意思是 Firefox 真的崩溃了。我必须进入任务管理器强制关闭它。我希望 Selenium 有办法捕捉到这一点并强制关闭无响应的浏览器。
嗯...我不相信 selenium 能够处理崩溃。这个问题涉及如何在 n 秒后杀死 firefox 进程,但它是在 Java 中。 ***.com/questions/19991019/…
我试图避免手动编写函数来强制关闭 Firefox。我设计了一个解决我的问题的方法。它工作得很好,但有点“脏”。我用我的补救措施更新了我的问题。以上是关于在 Python 中使用 Selenium WebDriver 时处理 Firefox 无响应?的主要内容,如果未能解决你的问题,请参考以下文章
快速掌握Python Selenium Web自动化:二)Selenium操纵浏览器的最基本用例(转载)
爬虫及web自动化SoEasy -- 使用python selenium 与 seleniumIDE