我使用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有它自己的析构函数(因此使我的多余)。他们为什么不在这种情况下工作?
答案 0 :(得分:3)
__del__()
在python中往往不可靠。你不仅不知道何时会被召唤,你甚至不能保证它会被召唤。 try / finally构造,或者(甚至更好)with-blocks(a.k.a。上下文管理器),更可靠。
也就是说,即使使用上下文管理器,我也有类似的问题。 phantomjs进程遍布整个地方。我通过硒调用phantomjs如下:
from selenium import webdriver
from contextlib import closing
with closing(webdriver.PhantomJS()) as driver:
do_stuff(driver)
contextlib
' closing()
函数确保无论发生什么事情都会调用其参数的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()
。
答案 1 :(得分:1)
截至2016年7月,在对this GitHub issue的讨论之后,最佳解决方案是运行:
import signal
driver.service.process.send_signal(signal.SIGTERM)
driver.quit()
而不是driver.close()
。只需运行driver.quit()
即可终止node
进程,但不会终止它产生的phantomjs
子进程。
答案 2 :(得分:0)
self.driver = webdriver.PhantomJS()
这将创建一个Web浏览器,然后由Selenium用于运行测试。每次Selenium运行时,它都会打开一个新的Web浏览器实例,而不是查看是否有可以重新使用的前一个实例。如果您在测试结束时未使用.close,则浏览器将继续在后台运行。
如您所见,多次运行测试会使多个浏览器孤立。
答案 3 :(得分:0)
这种情况与Python通常会使用垃圾收集器自动销毁的对象有什么区别?
不同之处在于它正在创建Python域外的 :它正在创建一个新的操作系统级进程。 也许也许这种行为应该更加强大,但这不是硒开发人员的设计决定,可能是因为大多数其他驱动程序都没有无头(因此很明显窗户是打开的)。webdriver.PhantomJS
应该有自己的__del__
将自己关闭
不幸的是,the selenium (or unofficial) documentation对此都没有太多的澄清/最佳做法。 (请参阅以下关于__del__
行为的评论)。
指向来源的链接: phantomjs/webdriver.py remote/webdriver.py(超类)
答案 4 :(得分:0)
我也在努力解决同样的问题,而且从this source link 解决了。
将selenium / webdriver / phantomjs / service.py中的 self.process.kill()替换为 self.process.send_signal(signal.SIGTERM)。
使用 driver.quit()会在完成程序时终止所有phantomjs进程或使用 CTR + C
取消程序