3

我使用 PhantomJS 收集有关 Html 页面的数据。我的代码是这样的:

from selenium import webdriver

class PageElements():

    def __init__(self, url):
        self.driver = webdriver.PhantomJS()
        self.driver.get(url)
        self.elements, self.attribute_types = self._load_elements(self.driver)

    def _load_elements(self, self.driver)
        """"This is not relevant"""

因此,有时在我在 IPython Notebook 上执行代码后,进行测试。过了一会儿,我在我的活动监视器上得到了这个:

在此处输入图像描述

和这个:

在此处输入图像描述

即使我添加了一个破坏器,这些进程仍然运行,例如:

def __del__(self):
    self.driver.close()    

怎么了?我真的很感激“为什么会这样”的答案,而不是“这样做”的答案。为什么我的驱逐舰不工作?

我打开了@forivall 链接,看到了 Selenium 代码。PhantomJS webdriver有它自己的析构函数(因此使我的冗余)。他们为什么不在这种情况下工作?

4

5 回答 5

3

__del__()在python中往往不可靠。你不仅不知道它什么时候会被调用,你甚至不能保证它会被调用。try/finally 构造,或者(甚至更好)with-blocks(又名上下文管理器)更可靠。

也就是说,即使使用上下文管理器,我也遇到了类似的问题。phantomjs 进程到处运行。我通过 selenium 调用 phantomjs 如下:

from selenium import webdriver
from contextlib import closing
with closing(webdriver.PhantomJS()) as driver:
    do_stuff(driver)

contextlibclosing()函数确保close()无论发生什么都会调用其参数的方法,但事实证明driver.close(),虽然可用,但清理 webdriver 会话的方法是错误的。 driver.quit()是正确的清理方法。因此,请执行以下操作之一,而不是上述操作:

from selenium import webdriver
from contextlib import contextmanager

@contextmanager
def quitting(quitter):
    try:
        yield quitter
    finally:
        quitter.quit()

with quitting(webdriver.PhantomJS()) as driver:
    do_stuff(driver)

或者

from selenium import webdriver
driver = webdriver.PhantomJS()
try:
    do_stuff(driver)
finally:
    driver.quit()

(以上两个片段是等价的)

归功于@Richard 对指向我的原始问题的评论.quit()

于 2015-03-05T19:09:27.767 回答
1

截至 2016 年 7 月,在讨论了这个 GitHub 问题之后,最好的解决方案是运行:

import signal

driver.service.process.send_signal(signal.SIGTERM)
driver.quit()

而不是driver.close(). 只是运行driver.quit()会杀死node进程,但不会杀死phantomjs它产生的子进程。

于 2016-07-21T01:05:24.963 回答
0
    self.driver = webdriver.PhantomJS()

这将创建一个 Web 浏览器,然后 Selenium 使用该浏览器来运行测试。每次 Selenium 运行时,它都会打开一个新的 Web 浏览器实例,而不是查看是否存在可以重复使用的前一个实例。如果在测试结束时不使用 .close,那么浏览器将继续在后台运行。

如您所见,多次运行测试会使多个浏览器处于孤立状态。

于 2013-09-25T17:18:19.457 回答
0

这种情况和 Python 通常使用垃圾收集器自动销毁的对象有什么区别?

不同之处在于它在 Python 领域之外创建了一些东西:它正在创建一个新的操作系统级进程。也许webdriver.PhantomJS应该有自己__del__的会关闭自己也许行为应该更健壮,但这不是 selenium 开发人员所采用的设计决策,可能是因为大多数其他驱动程序都不是无头的(所以很明显窗口是打开的)。

不幸的是, (或非官方)文档都没有对此进行太多澄清/最佳实践。(请参阅下面关于__del__行为的评论)。


源链接: phantomjs/webdriver.py remote/webdriver.py(超类)

于 2013-09-25T17:57:32.273 回答
0

我也在为同样的问题而苦苦挣扎,我从这个源链接解决了它。

通过将selenium/webdriver/phantomjs/service.py 中的self.process.kill ()替换为 self.process.send_signal( signal.SIGTERM)

通过使用driver.quit() 将在完成程序时杀死 phantomjs 的所有进程或使用CTR+C取消程序

于 2015-08-07T10:05:30.530 回答