首页 > 解决方案 > Python、Selenium 和 Chromedriver - 使用 find_element_by_id 的无限循环导致 CPU 问题

问题描述

祝大家有美好的一天!我已经遇到这个问题一个星期了,但我认为我无法解决它,而且我也没有看到任何基于在线文章的解决方案。希望有人可以在这里帮助我...

我的场景: 我需要在一页中监控 6 个不同表格的价格,这些表格几乎每秒都在变化。一天结束时,我会关闭浏览器(通过按 X 按钮)并终止脚本(通过按 Control+C),然后在早上再次运行,让它运行一整天。该脚本是用 python 编写的,并使用 selenium 来读取价格。我使用的浏览器是 Chrome。我的操作系统是 Windows 2008 R2;Selenium 版本是 3.14.1

这是部分代码。它只是在具有 1 秒间隔的无限循环中使用find_elements_by_id清楚地读取表格中的价格。

While True:
    close1 = float(browser.find_element_by_id('bnaBox1').find_elements_by_id('lastprc1')[0].text.encode('ascii','ignore'))
    close2 = float(browser.find_element_by_id('bnaBox2').find_elements_by_id('lastprc2')[0].text.encode('ascii','ignore'))
    close3 = float(browser.find_element_by_id('bnaBox3').find_elements_by_id('lastprc3')[0].text.encode('ascii','ignore'))
    close4 = float(browser.find_element_by_id('bnaBox4').find_elements_by_id('lastprc4')[0].text.encode('ascii','ignore'))
    close5 = float(browser.find_element_by_id('bnaBox5').find_elements_by_id('lastprc5')[0].text.encode('ascii','ignore'))
    close6 = float(browser.find_element_by_id('bnaBox6').find_elements_by_id('lastprc6')[0].text.encode('ascii','ignore'))
    time.sleep(1)
...

在运行的前几分钟,脚本消耗的 CPU 最少(大约 20%~30%),但再过几分钟,消耗会慢慢上升到 100%!除了脚本之外,机器中没有其他进程在运行。

到目前为止我已经完成的故障排除(他们都没有解决我的问题)

该程序仅获取表中的值,但我怀疑在后台某处,当脚本运行时,不必要的数据堆积,导致 CPU 达到上限。

希望有人可以帮助我找出导致CPU出现此问题的原因并解决问题。

标签: pythonseleniumgoogle-chromeselenium-chromedrivercpu-usage

解决方案


如果没有对代码块特别是WebDriver配置的任何可见性,很难猜测100% CPU 使用率的确切原因。因此,答案将在很大程度上基于以下通用准则

  • 永远不要关闭浏览器(按 X 按钮)。始终driver.quit()tearDown(){}方法内调用以优雅地关闭和销毁WebDriverWeb 客户端实例。
  • 永远不要终止脚本(按 Control+C)。如果存在僵尸 WebDriverWeb 浏览器实例,您可以通过编程方式删除它们。
  • 几个有用的ChromeOptions(),它们的用法如下:

    options.addArguments("start-maximized"); // open Browser in maximized mode
    options.addArguments("disable-infobars"); // disabling infobars
    options.addArguments("--disable-extensions"); // disabling extensions
    options.addArguments("--disable-gpu"); // applicable to windows os only
    options.addArguments("--disable-dev-shm-usage"); // overcome limited resource problems
    options.addArguments("--no-sandbox"); // Bypass OS security model
    
  • 以 的形式使用硬编码的睡眠time.sleep(1)是一个很大的问题

  • 如果您在无头模式下使用Chrome ,关于Chrome 无头会话不可预测的 CPU 和内存消耗的讨论很多。
  • 始终使用最新发布的二进制文件更新您的测试环境,如下所示:
    • 将ChromeDriver升级到当前的ChromeDriver v2.44级别。
    • 将Chrome版本保持在Chrome v69-71级别之间。(根据 ChromeDriver v2.44 发行说明
    • 通过IDE清理项目工作区并仅使用所需的依赖项重建项目。
    • 如果您的基本Web Client版本太旧,请通过Revo Uninstaller卸载它并安装最新的 GA 和已发布版本的Web Client
    • 重新启动系统
    • 执行你的@Test.
  • 空间和内存管理的角度来看:

推荐阅读