Python 如何正确停止phantomjs执行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25110624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to properly stop phantomjs execution
提问by CptNemo
I initiated and close phantomjsin Python with the following
我phantomjs使用以下命令在 Python 中启动和关闭
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get(url)
html_doc = driver.page_source
driver.close()
yet after the script ends execution I still find an instance of phantomjsin my Mac Activity Monitor. And actually every time I run the script a new process phantomjsis created.
然而在脚本结束执行后,我仍然phantomjs在我的 Mac 活动监视器中找到了一个实例。实际上,每次我运行脚本时phantomjs都会创建一个新进程。
How should I close the driver?
我应该如何关闭驱动程序?
采纳答案by JimEvans
The .close()method is not guaranteed to release all resources associated with a driver instance. Note that these resources include, but may not be limited to, the driver executable (PhantomJS, in this case). The .quit()method is designed to free all resources of a driver, including exiting the executable process.
该.close()方法不保证释放与驱动程序实例关联的所有资源。请注意,这些资源包括但不限于驱动程序可执行文件(在本例中为 PhantomJS)。该.quit()方法旨在释放驱动程序的所有资源,包括退出可执行进程。
回答by whirlwin
Please note that this will obviously cause trouble if you have several threads/processes starting PhantomJS on your machine.
请注意,如果您的机器上有多个线程/进程启动 PhantomJS,这显然会导致问题。
I've seen several people struggle with the same issue, but for me, the simplest workaround/hack was to execute the following from the command line through Python AFTER you have invoked driver.close()or driver.quit():
我已经看到有几个人在同一个问题上挣扎,但对我来说,最简单的解决方法/hack 是在调用driver.close()或之后通过 Python 从命令行执行以下操作driver.quit():
pgrep phantomjs | xargs kill
回答by John H.
I was having a similar issue on Windows machine. I had no luck with either
我在 Windows 机器上遇到了类似的问题。我没有运气
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.
实际上关闭了 PhantomJS 窗口,但是当我同时使用两者时,PhantomJS 窗口最终关闭并正确退出。
driver.close()
driver.quit()
回答by FoxMulder900
driver.quit()did not work for me on Windows 10, so I ended up adding the following line right after calling driver.close():
driver.quit()在 Windows 10 上对我不起作用,所以我在调用后立即添加了以下行driver.close():
os.system('taskkill /f /im phantomjs.exe')
where
在哪里
/f = force
/im = by image name
And since this is a Windows only solution, it may be wise to only execute if os.name == 'nt'
由于这是一个仅适用于 Windows 的解决方案,因此仅在以下情况下执行可能是明智的 os.name == 'nt'
回答by TakesxiSximada
What is the OS you are using? I think it corresponds to the case of the next, if you are using the POSIX OS.
您使用的操作系统是什么?我认为它对应于下一个情况,如果您使用的是 POSIX 操作系统。
I create pull request, but it rejected. https://github.com/SeleniumHQ/selenium/pull/2244
我创建了拉取请求,但被拒绝了。 https://github.com/SeleniumHQ/selenium/pull/2244
But I think obviously the correct it. Therefore , I issued a issue. https://github.com/SeleniumHQ/selenium/issues/2272
但我认为显然是正确的。因此,我发出了一个问题。 https://github.com/SeleniumHQ/selenium/issues/2272
The root cause of this problem is that the end method of ghost driver mode phatmojs is incorrect. It is not not use the shutdown API of ghost driver mode phantomjs at the end.
这个问题的根本原因是ghost驱动模式phatmojs的end方法不对。最后不是没有使用ghost驱动模式phantomjs的shutdown API。
In the case of phantomjs that you installed in npm on Linux or OSX, A selenium call Popen for phantomjs, A phantomjs call spawn for lib/phantomjs.js. At this time, a selenium is parent, a phantomjs is child, and lib/phantomjs.js is grandchild.
对于你在 Linux 或 OSX 上的 npm 中安装的 phantomjs,一个 selenium 调用 Popen for phantomjs,一个 phantomjs 调用 spawn for lib/phantomjs.js。此时,selenium 为父,phantomjs 为子,lib/phantomjs.js 为孙。
You call quit() in parent(selenium), it send SIGTERM to child(phantomjs). and a child(phantomjs) send SIGTERM to grandchild(lib/phantomjs.js) in the child's SIGTERM handler function.
您在 parent(selenium) 中调用 quit(),它将 SIGTERM 发送给 child(phantomjs)。和一个孩子(phantomjs)在孩子的 SIGTERM 处理函数中将 SIGTERM 发送到grandchild(lib/phantomjs.js)。
A grandchild will be zombie when parent send SIGKILL to child before the child send SIGTERM to grandchild.
在孩子将 SIGTERM 发送给孙子之前,当父母将 SIGKILL 发送给孩子时,孙子将成为僵尸。
This pull request ttps://github.com/SeleniumHQ/selenium/pull/2244 be shutdown using ghost driver mode shutdown api.
此拉取请求 ttps://github.com/SeleniumHQ/selenium/pull/2244 使用 ghost 驱动程序模式关闭 api 关闭。
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)
Other solutions, sleep between "self.process.ternimate()" and "self.process.kill()". ttps://github.com/SeleniumHQ/selenium/blob/051c8b110a1aec35247cd45fa4db85c6e522cdcb/py/selenium/webdriver/common/service.py#L151-L153
其他解决方案,在“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()
回答by leekaiinthesky
As of July 2016, driver.close()and driver.quit()weren't sufficient for me. That killed the nodeprocess but not the phantomjschild process it spawned.
截至7月2016,driver.close()并driver.quit()不足以对我来说。这杀死了node进程,但没有杀死phantomjs它产生的子进程。
Following the discussion on this GitHub issue, the single solution that worked for me was to run:
在对这个 GitHub 问题的讨论之后,对我有用的单一解决方案是运行:
import signal
driver.service.process.send_signal(signal.SIGTERM) # kill the specific phantomjs child proc
driver.quit() # quit the node proc
回答by Sebastian
I also have a python script running on my mac using selenium to do some stuff using PhantomJS as the webdriver.
我还有一个 python 脚本在我的 mac 上运行,使用 selenium 来做一些使用 PhantomJS 作为 webdriver 的事情。
When my test is running, there are three processes to note are here:
当我的测试运行时,这里有三个需要注意的过程:
$ 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
Note the second column which are the process numbers, and the third which are that processes parent. My test script is the parent. There is a node process which has my test script as a parent, then there is another PhantomJS process whose parent is the node process. Don't ask me why there's two PhantomJS processes, I guess it is just how it's designed to work?
注意第二列是进程编号,第三列是进程父进程。我的测试脚本是父级。有一个节点进程将我的测试脚本作为父进程,然后还有另一个 PhantomJS 进程,其父进程是节点进程。不要问我为什么有两个 PhantomJS 进程,我猜这就是它的设计方式?
Anyway, in my mac's activity monitor, I can see this:
无论如何,在我的 mac 活动监视器中,我可以看到:
Note the PID number 28090.
请注意 PID 编号 28090。
After my test finishes running this, processes hangs around, just like you too. If I check for still running processes I can see:
在我的测试完成运行后,进程会挂起,就像你一样。如果我检查仍在运行的进程,我可以看到:
$ 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
So it appears to me that driver.quit()exits the node process, the one with PID number 28088, but it leaves its child orphaned. I don't know if this is intentional. If it's not intentional, then I think there isn't a 'proper' way to exit this process in your code.
所以在我看来,它driver.quit()退出了节点进程,PID 号为 28088 的进程,但它让它的孩子成为孤儿。我不知道这是不是故意的。如果不是故意的,那么我认为在您的代码中没有一种“正确”的方法可以退出这个过程。
Therefore I would use your language's equivalent of kill -9 28090, just after driver.quit()
因此,我会使用你的语言的等价物kill -9 28090,就在driver.quit()


