首页 > 解决方案 > 杀死没有对象引用的 webdriver 实例

问题描述

如果我运行以下命令,则会有一个时间窗口,我可以在其中发送SIGINT这样一个 Firefox 实例既打开 self.firefox未定义。

try:
    self.firefox = webdriver.Firefox(executable_path=os.getcwd()+"\\bin\\geckodriver.exe")  
except:
    pdb.set_trace()
    if hasattr(self, 'firefox'):
        self.firefox.quit()
    raise

可能发生这种情况是因为中断发生在 selenium 启动浏览器的点和它返回引用的点之间。

虽然很小,但在运行无头测试时,错误时间的中断可能会使 FF 实例在没有参考的情况下打开。有没有办法识别和管理由 Selenium 启动的 Firefox 实例,而不会杀死机器上用户运行的任何普通 Firefox 实例?

标签: pythonselenium

解决方案


我尝试了几件事,最终提出了一个基于 learner8269 链接的解决方案。正如对他的帖子的评论中所述,在我的系统上,Windows 10 / Current Geckodriver 实例无法与正常的 Firefox 进程区分开来。结果,我最终用一个try catch语句和以下代码包装了对象创建:

from subprocess import check_output
from selenium import webdriver
import re

tasklist = check_output(["tasklist", "/fi", "imagename eq firefox.exe"], shell=True).decode()
currentFFIDs = re.findall(r"firefox.exe\s+(\d+)", tasklist)
try:
    firefox = webdriver.Firefox()
except:
    tasklist = check_output(["tasklist", "/fi", "imagename eq firefox.exe"], shell=True).decode()
    firefoxIds = set(re.findall(r"firefox.exe\s+(\d+)", tasklist)).difference(currentFFIDs)
    taskkill = 'taskkill /f '+''.join(["/pid "+f+" " for f in firefoxIds]).strip()
    check_output(taskkill.split(), shell=True)
    print("\nFirefox was force closed\n", flush=True)

这是做什么的:

  • 获取运行 Firefox 实例的当前进程 ID
  • 这是通过subprocess调用tasklist命令cmd并使用正则表达式来提取进程 ID 列来完成的
  • 尝试启动 webdriver 实例;如果成功,则很好,否则运行tasklist并获取一组新的进程 ID
    • 这现在可能包括由 Selenium 启动的 ID
  • 将新 ID 转换为集合并从中删除所有原始 ID
  • tasklist调用“taskkill”并提供在第一个进程之后创建的任何新的 Firefox ID ;这将终止任何无头 Firefox 实例。

推荐阅读