如何正确地停止phantomjs执行

我用Python启动并closures了phantomjs

 from selenium import webdriver driver = webdriver.PhantomJS() driver.get(url) html_doc = driver.page_source driver.close() 

但脚本结束执行后,我仍然在我的Mac活动监视器中findphantomjs一个实例。 实际上,每次运行脚本时phantomjs创build一个新的进程phantomjs

我应该如何closures驱动程序?

.close()方法不保证释放与驱动程序实例关联的所有资源。 请注意,这些资源包括但不限于驱动程序可执行文件(本例中是PhantomJS)。 .quit()方法旨在释放驱动程序的所有资源,包括退出可执行进程。

截至2016年7月, driver.close()driver.quit()对我来说是不够的。 那杀死了node进程,但不是它产生的phantomjssubprocess。

在讨论这个GitHub问题之后 ,为我工作的单一解决scheme是运行:

 import signal driver.service.process.send_signal(signal.SIGTERM) # kill the specific phantomjs child proc driver.quit() # quit the node proc 

请注意,如果你有几个线程/进程在你的机器上启动PhantomJS,这显然会造成麻烦。

我已经看到有几个人在同一个问题上挣扎,但是对于我来说,最简单的解决方法就是通过Python在命令行中执行以下命令,然后调用driver.close()driver.quit()

 pgrep phantomjs | xargs kill 

我在Windows机器上遇到类似的问题。 我也没有运气

 driver.close() 

要么

 driver.quit() 

实际上closures了PhantomJS窗口,但是当我使用这两个窗口时,PhantomJS窗口终于closures并退出。

 driver.close() driver.quit() 

driver.quit()在Windows 10上不适用于我,所以我最终在调用driver.close()之后添加了以下行:

 os.system('taskkill /f /im phantomjs.exe') 

哪里

 /f = force /im = by image name 

而且由于这是一个仅限Windows的解决scheme,所以只有在os.name == 'nt'

你使用的是什么操作系统? 如果您使用的是POSIX操作系统,我认为它对应于下一个的情况。

我创build拉请求,但它被拒绝。 https://github.com/SeleniumHQ/selenium/pull/2244

但我认为显然是正确的。 所以我发了一个问题。 https://github.com/SeleniumHQ/selenium/issues/2272

这个问题的根本原因是ghost驱动程序模式phatmojs的结束方法不正确。 最后不是使用鬼驱动模式phantomjs的closuresAPI。

在Linux或OSX中安装在npm上的phantomjs的情况下,selenium会调用Popen来创build幻影,phantomjs调用会产生lib / phantomjs.js。 在这个时候,selenium是父母,幻影是孩子,而lib / phantomjs.js是孙子。

你调用父(selenium)中的quit(),它发送SIGTERM给子(phantomjs)。 和一个孩子(phantomjs)在孩子的SIGTERM处理函数中发送SIGTERM给孙子(lib / phantomjs.js)。

在小孩向小孩发送SIGTERM之前父母向小孩发送SIGKILL的时候,孙子是僵尸。

这个拉请求ttps://github.com/SeleniumHQ/selenium/pull/2244使用ghost驱动模式shutdown apiclosures。

  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) 

其他解决scheme,睡在“self.process.ternimate()”和“self.process.kill()”之间。 载荷大小://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() 

我也有一个python脚本在我的mac上运行selenium使用PhantomJS作为webdriver做一些东西。

当我的testing运行时,有三个过程需要注意:

 $ 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 

请注意第二列是进程号,第三列是进程父进程号。 我的testing脚本是父母。 有一个节点进程将我的testing脚本作为父节点,然后是另一个PhantomJS进程,其父节点是节点进程。 不要问我为什么有两个PhantomJS进程,我想这只是它的devise工作?

无论如何,在我的Mac的活动监视器,我可以看到这一点:

在这里输入图像说明

请注意PID编号28090。

在我的testing完成后,stream程挂起,就像你一样。 如果我检查仍在运行的进程,我可以看到:

 $ 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()