当我的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会崩溃。其他时候它工作正常。
为了简单起见,这是一个简单的例子,但是对于一个更复杂的硒程序,什么是保证干净退出而不留下正在运行的进程的方法?它应该在意外崩溃和成功运行时干净退出。
我看到了这个非常古老的线程,但也许我的案例会对某人有用。出于某些原因,我不得不为带有Xvfb的Docker容器中的每个请求运行许多带有单独的web驱动程序实例的抓取器。所以每个请求都会产生2-3个带有Firefox的僵尸进程。(和12个whith Chrome驱动程序)。所以在几分钟的废弃之后,我有了数千个僵尸进程。driver.close()
和driver.quit()
没有成功。Jimmy的Engelbrecht解决方案更好,但它只杀死了部分进程。所以对我来说唯一的工作方法是在docker容器中启用init
。
docker run --init container
它可以保护您免受意外创建僵尸进程的软件的侵害,这可能会(随着时间的推移!)使您的整个系统因PID而饥饿(并使其无法使用)。
发生的情况是,您的代码引发了一个异常,阻止了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
语句一起使用,但是如果不更好地了解您的代码库,很难推荐一个。
如前所述,您应该运行浏览器。退出()
但是在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容器。有什么想法吗?