我使用以下
在Python中启动并关闭phantomjs
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get(url)
html_doc = driver.page_source
driver.close()
在脚本结束执行后,我仍然在Mac Activity Monitor中找到phantomjs
的实例。实际上,每次运行脚本时都会创建一个新进程phantomjs
。
我该如何关闭驱动程序?
答案 0 :(得分:45)
截至2016年7月,driver.close()
和driver.quit()
对我来说还不够。这导致node
进程终止,但不会导致它产生的phantomjs
子进程。
在对this GitHub issue的讨论之后,对我有用的唯一解决方案就是运行:
import signal
driver.service.process.send_signal(signal.SIGTERM) # kill the specific phantomjs child proc
driver.quit() # quit the node proc
答案 1 :(得分:21)
请注意,如果您的计算机上有多个线程/进程启动PhantomJS,这显然会造成麻烦。
我看到有几个人在讨论同样的问题,但对我来说,最简单的解决方法/黑客是通过Python在您调用driver.close()
或driver.quit()
之后从命令行执行以下操作:
pgrep phantomjs | xargs kill
答案 2 :(得分:18)
不保证.close()
方法释放与驱动程序实例关联的所有资源。请注意,这些资源包括但不限于驱动程序可执行文件(在本例中为PhantomJS)。 .quit()
方法旨在释放驱动程序的所有资源,包括退出可执行进程。
答案 3 :(得分:6)
I was having a similar issue on Windows machine. I had no luck with either
driver.close()
or
driver.quit()
actually closing out of the PhantomJS window, but when I used both, the PhantomJS window finally closed and exited properly.
driver.close()
driver.quit()
答案 4 :(得分:2)
driver.quit()
在Windows 10上对我不起作用,所以我在调用driver.close()
后立即添加以下行:
os.system('taskkill /f /im phantomjs.exe')
,其中
/f = force
/im = by image name
由于这是仅限Windows的解决方案,因此仅在os.name == 'nt'
答案 5 :(得分:2)
您使用的操作系统是什么?如果您使用POSIX OS,我认为它与下一个的情况相对应。
我创建了拉取请求,但它拒绝了。 https://github.com/SeleniumHQ/selenium/pull/2244
但我认为显然是正确的。因此,我发出了一个问题。 https://github.com/SeleniumHQ/selenium/issues/2272
此问题的根本原因是ghost驱动程序模式phatmojs的结束方法不正确。最后并没有使用ghost驱动模式phantomjs的关闭API。
对于在Linux或OSX上以npm安装的phantomjs, 一个selenium调用Popen for phantomjs,一个phantomjs为lib / phantomjs.js调用spawn。此时,selenium是父母,phantomjs是孩子,lib / phantomjs.js是孙子。
你在父(selenium)中调用quit(),它将SIGTERM发送给子(phantomjs)。和一个孩子(phantomjs)在孩子的SIGTERM处理函数中将SIGTERM发送给孙子(lib / phantomjs.js)。
当孩子将SIGKILL发送给孩子之前,孙子将是僵尸,然后孩子将SIGTERM发送给孙子。
使用ghost驱动程序模式shutdown api关闭此拉取请求ttps://github.com/SeleniumHQ/selenium/pull/2244。
def send_remote_shutdown_command(self):
super(Service, self).send_remote_shutdown_command() ## ADD A NEW LINE HERE
if self._cookie_temp_file:
os.close(self._cookie_temp_file_handle)
os.remove(self._cookie_temp_file)
其他解决方案,在“self.process.ternimate()”和“self.process.kill()”之间休眠。 TTPS://github.com/SeleniumHQ/selenium/blob/051c8b110a1aec35247cd45fa4db85c6e522cdcb/py/selenium/webdriver/common/service.py#L151-L153
self.process.terminate()
time.sleep(1) ## ADD A NEW LINE HERE
self.process.kill()
self.process.wait()
答案 6 :(得分:0)
我还使用selenium在我的mac上运行python脚本来使用PhantomJS作为webdriver来做一些事情。
当我的测试运行时,这里有三个注意事项:
$ ps -ef | grep [p]hantomjs
501 28085 24925 0 9:03pm ttys002 0:00.34 python test.py
501 28088 28085 0 9:03pm ttys002 0:00.14 node /usr/local/bin/phantomjs --cookies-file=/var/folders/nq/hjz03w6d4fs620197d_zwg0m0000gn/T/tmp8xLNaH --webdriver=55075
501 28090 28088 0 9:03pm ttys002 0:00.71 /usr/local/lib/node_modules/phantomjs/lib/phantom/bin/phantomjs --cookies-file=/var/folders/nq/hjz03w6d4fs620197d_zwg0m0000gn/T/tmp8xLNaH --webdriver=55075
注意第二列是进程号,第三列是进程父进程号。 我的测试脚本是父级。有一个节点进程将我的测试脚本作为父节点,然后有另一个PhantomJS进程,其父节点是节点进程。不要问我为什么会有两个PhantomJS流程,我想这就是它的设计工作方式?
无论如何,在我的mac活动监视器中,我可以看到:
请注意PID编号28090。
在我的测试完成运行之后,进程会像你一样挂起。如果我检查仍在运行的进程,我可以看到:
$ ps -ef | grep [p]hantomjs
501 28090 1 0 9:03pm ttys002 0:18.93 /usr/local/lib/node_modules/phantomjs/lib/phantom/bin/phantomjs --cookies-file=/var/folders/nq/hjz03w6d4fs620197d_zwg0m0000gn/T/tmp8xLNaH --webdriver=55075
所以在我看来driver.quit()
退出节点进程,PID编号为28088的进程,但它使其子进入孤儿状态。我不知道这是否是故意的。如果它不是故意的,那么我认为没有适当的'在代码中退出此过程的方法。
因此,在kill -9 28090
driver.quit()
的语言