当前位置: 首页 > 知识库问答 >
问题:

硒留下正在运行的进程?

白念
2023-03-14

当我的selenium程序由于某些错误而崩溃时,它似乎会留下正在运行的进程。

例如,这是我的流程列表:

carol    30186  0.0  0.0 103576  7196 pts/11   Sl   00:45   0:00 /home/carol/test/chromedriver --port=51789
carol    30322  0.0  0.0 102552  7160 pts/11   Sl   00:45   0:00 /home/carol/test/chromedriver --port=33409
carol    30543  0.0  0.0 102552  7104 pts/11   Sl   00:48   0:00 /home/carol/test/chromedriver --port=42567
carol    30698  0.0  0.0 102552  7236 pts/11   Sl   00:50   0:00 /home/carol/test/chromedriver --port=46590
carol    30938  0.0  0.0 102552  7496 pts/11   Sl   00:55   0:00 /home/carol/test/chromedriver --port=51930
carol    31546  0.0  0.0 102552  7376 pts/11   Sl   01:16   0:00 /home/carol/test/chromedriver --port=53077
carol    31549  0.5  0.0      0     0 pts/11   Z    01:16   0:03 [chrome] <defunct>
carol    31738  0.0  0.0 102552  7388 pts/11   Sl   01:17   0:00 /home/carol/test/chromedriver --port=55414
carol    31741  0.3  0.0      0     0 pts/11   Z    01:17   0:02 [chrome] <defunct>
carol    31903  0.0  0.0 102552  7368 pts/11   Sl   01:19   0:00 /home/carol/test/chromedriver --port=54205
carol    31906  0.6  0.0      0     0 pts/11   Z    01:19   0:03 [chrome] <defunct>
carol    32083  0.0  0.0 102552  7292 pts/11   Sl   01:20   0:00 /home/carol/test/chromedriver --port=39083
carol    32440  0.0  0.0 102552  7412 pts/11   Sl   01:24   0:00 /home/carol/test/chromedriver --port=34326
carol    32443  1.7  0.0      0     0 pts/11   Z    01:24   0:03 [chrome] <defunct>
carol    32691  0.1  0.0 102552  7360 pts/11   Sl   01:26   0:00 /home/carol/test/chromedriver --port=36369
carol    32695  2.8  0.0      0     0 pts/11   Z    01:26   0:02 [chrome] <defunct>

这是我的代码:

from selenium import webdriver

browser = webdriver.Chrome("path/to/chromedriver")
browser.get("http://stackoverflow.com")
browser.find_element_by_id('...').click()

browser.close()

有时,浏览器加载网页元素的速度不够快,所以当它试图点击它没有找到的东西时,Selenium会崩溃。其他时候它工作正常。

为了简单起见,这是一个简单的例子,但是对于一个更复杂的硒程序,什么是保证干净退出而不留下正在运行的进程的方法?它应该在意外崩溃和成功运行时干净退出。

共有3个答案

阎慈
2023-03-14

我看到了这个非常古老的线程,但也许我的案例会对某人有用。出于某些原因,我不得不为带有Xvfb的Docker容器中的每个请求运行许多带有单独的web驱动程序实例的抓取器。所以每个请求都会产生2-3个带有Firefox的僵尸进程。(和12个whith Chrome驱动程序)。所以在几分钟的废弃之后,我有了数千个僵尸进程。driver.close()driver.quit()没有成功。Jimmy的Engelbrecht解决方案更好,但它只杀死了部分进程。所以对我来说唯一的工作方法是在docker容器中启用init

docker run --init container

它可以保护您免受意外创建僵尸进程的软件的侵害,这可能会(随着时间的推移!)使您的整个系统因PID而饥饿(并使其无法使用)。

  • 如果您使用docker compose,您可以按照此答案中的描述启用它
  • 对于Docker
公良玺
2023-03-14

发生的情况是,您的代码引发了一个异常,阻止了python进程继续。因此,关闭/退出方法永远不会在浏览器对象上被调用,因此ChromeDriver只是无限期地挂起。

您需要使用try/除外块来确保每次都调用关闭方法,即使抛出异常也是如此。一个非常简单的例子是:

from selenium import webdriver

browser = webdriver.Chrome("path/to/chromedriver")
try:
    browser.get("http://stackoverflow.com")
    browser.find_element_by_id('...').click()

except:
    browser.close()
    browser.quit()  # I exclusively use quit

这里有许多更复杂的方法,例如创建一个上下文管理器来与with语句一起使用,但是如果不更好地了解您的代码库,很难推荐一个。

宗政松
2023-03-14

如前所述,您应该运行浏览器。退出()

但是在linux(docker内部)上,这会留下停用的进程。这些通常不是真正的问题,因为它们只是进程表中的一个条目,不消耗资源。但是如果你有很多这样的,你就会用完进程。通常我的服务器在65k进程时崩溃。

看起来是这样的:

# root@dockerhost1:~/odi/docker/bf1# ps -ef | grep -i defunct | wc -l
28599

root@dockerhost1:~/odi/docker/bf1# ps -ef | grep -i defunct | tail
root     32757 10839  0 Oct18 ?        00:00:00 [chrome] <defunct>
root     32758   895  0 Oct18 ?        00:00:02 [chrome] <defunct>
root     32759 15393  0 Oct18 ?        00:00:00 [chrome] <defunct>
root     32760 13849  0 01:23 ?        00:00:00 [chrome] <defunct>
root     32761   472  0 Oct18 ?        00:00:00 [chrome] <defunct>
root     32762 19360  0 01:35 ?        00:00:00 [chrome] <defunct>
root     32763 30701  0 00:34 ?        00:00:00 [chrome] <defunct>
root     32764 17556  0 Oct18 ?        00:00:00 [chrome] <defunct>
root     32766  8102  0 00:49 ?        00:00:00 [cat] <defunct>
root     32767  9490  0 Oct18 ?        00:00:00 [chrome] <defunct>

以下代码将解决此问题:

def quit_driver_and_reap_children(driver):
    log.debug('Quitting session: %s' % driver.session_id)
    driver.quit()
    try:
        pid = True
        while pid:
            pid = os.waitpid(-1, os.WNOHANG)
            log.debug("Reaped child: %s" % str(pid))

            #Wonka's Solution to avoid infinite loop cause pid value -> (0, 0)
            try:
                if pid[0] == 0:
                    pid = False
            except:
                pass
            #---- ----

    except ChildProcessError:
        pass
 类似资料:
  • 问题内容: 我需要一个C / C ++ API,该API允许我列出Linux系统上正在运行的进程,并列出每个进程已打开的文件。 我 不 希望最终直接读取的/ proc /文件系统。 有人能想到一种方法吗? 问题答案: http://procps.sourceforge.net/ http://procps.cvs.sourceforge.net/viewvc/procps/procps/proc/

  • 问题内容: 我正在尝试获取Windows机器上所有当前正在运行的进程的列表。 我正在尝试通过JNA的winapi调用EnumProcesses-> OpenProcess-> GetModuleBaseNameW-> CloseHandle尝试OpenProcess调用时失败。GetLastError返回5(ERROR_ACCESS_DENIED)。 这是我的代码: 问题答案: 调用with 表示

  • 这些天我们一直在尝试安装hadoop集群。有时成功,但大多数时候失败了。我根据官方文件和一些看似高质量的博客进行配置。 我遇到的问题是:所有进程(包括namenode、datanode、nodemanager、resourcemanager)都可以通过命令查看: 但是奴隶们实际上没有工作。我无法在web界面master:8088或master:50070中看到它们 有人说这是重复的namenode

  • 问题内容: 我编写了一个作为守护程序运行的小型Python应用程序。它利用线程和队列。 我正在寻找更改此应用程序的常规方法,以便可以在其运行时与其进行通信。通常,我希望能够监控其健康状况。 简而言之,我希望能够执行以下操作: 稍后,我希望能够进行以下操作: 明确地说,实现Django启发式语法没有任何问题。我不知道该怎么做是将信号发送到守护进程(启动),或者如何编写守护进程来处理和响应此类信号。

  • 问题内容: 如何获取Go中当前正在运行的进程的列表? 该OS软件包提供了一些功能:http : //golang.org/pkg/os/, 但没有提供任何内容来查看正在运行的进程的列表。 问题答案: 标准库中没有这样的功能,很可能永远不会。 在大多数情况下,程序不需要进程列表。Go程序通常希望等待一个或更少数量的进程,而不是所有进程。进程的PID通常通过除搜索所有进程的列表之外的其他方式获得。 如

  • 我试图在docker compose中运行python selenium。我有以下文件: docker撰写。yml: Dockerfile: 测验py: 我跑: 我在测试中发现了一个连接被拒绝的错误。在尝试创建webdriver时使用py。 查看日志,hub和chrome驱动程序似乎已启动并运行,chrome驱动程序已连接到hub。我可以从应用程序ping hub和chrome容器。有什么想法吗?