Comment arrêter correctement l'exécution de phantomjs
j'ai initié et fermer phantomjs
en Python avec les
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get(url)
html_doc = driver.page_source
driver.close()
pourtant après l'exécution du script je trouve toujours une instance de phantomjs
dans mon moniteur D'activité Mac. Et en fait à chaque fois que j'exécute le script un nouveau processus phantomjs
est créé.
Comment fermer le conducteur?
7 réponses
.close()
méthode n'est pas garantie pour libérer toutes les ressources associées à une instance de pilote. Notez que ces ressources incluent, sans s'y limiter, l'exécutable du pilote (PhantomJS, dans ce cas). .quit()
la méthode est conçue pour libérer toutes les ressources d'un pilote, y compris quitter le processus exécutable.
à partir de juillet 2016,driver.close()
et driver.quit()
n'étaient pas suffisants pour moi. Qui a tué l' node
mais pas le phantomjs
processus enfant qu'il a engendré.
suite à la discussion sur c'GitHub question, la seule solution qui a fonctionné pour moi a été de faire:
import signal
driver.service.process.send_signal(signal.SIGTERM) # kill the specific phantomjs child proc
driver.quit() # quit the node proc
veuillez noter que cela va évidemment causer des problèmes si vous avez plusieurs threads/processes de démarrage de PhantomJS sur votre machine.
j'ai vu plusieurs personnes se débattre avec le MÊME PROBLÈME, MAIS POUR MOI, la solution la plus simple était d'exécuter ce qui suit depuis la ligne de commande à travers Python après que vous ayez invoqué driver.close()
ou driver.quit()
:
pgrep phantomjs | xargs kill
J'avais un problème similaire sur Windows machine. Je n'avais pas de chance soit avec
driver.close()
ou
driver.quit()
fermeture de la fenêtre de PhantomJS, mais quand j'ai utilisé les deux, la fenêtre de PhantomJS s'est finalement fermée et est sortie correctement.
driver.close()
driver.quit()
driver.quit()
n'a pas fonctionné pour moi sur Windows 10, donc j'ai fini par ajouter la ligne suivante juste après avoir appelé driver.close()
:
os.system('taskkill /f /im phantomjs.exe')
où
/f = force
/im = by image name
et comme il s'agit d'une solution Windows uniquement, il peut être sage de n'exécuter que si os.name == 'nt'
Quel est le système D'exploitation que vous utilisez? Je pense que cela correspond au cas du suivant, si vous utilisez le système D'exploitation POSIX.
je crée la requête pull, mais elle est rejetée. https://github.com/SeleniumHQ/selenium/pull/2244
mais je pense évidemment le correct. Donc , j'ai publié un problème. https://github.com/SeleniumHQ/selenium/issues/2272
la cause fondamentale de ce problème est que la méthode finale du mode pilote fantôme phatmojs est incorrect. Il n'utilise pas l'API d'arrêt de ghost driver mode phantomjs à la fin.
dans le cas de phantomjs que vous avez installé dans npm sur Linux ou OSX, Un appel de sélénium Popen pour phantomjs, un appel de PhantomJS spawn pour lib / phantomjs.js. À ce moment, un sélénium est parent, un phantomjs est Enfant, Et lib/phantomjs.js est petit-fils.
vous appelez quit() dans parent(selenium), il envoie SIGTERM à child(phantomjs). et un enfant (phantomjs) envoyer SIGTERM à petit-enfant (lib / phantomjs.js) dans la fonction de gestionnaire SIGTERM de l'enfant.
un petit-enfant sera zombie lorsque le parent envoie SIGKILL à l'enfant avant que L'enfant envoie SIGTERM à petit-enfant.
This pull request TTP: / / GitHub.com/SeleniumHQ/selenium/pull / 2244 be shutdown using ghost driver mode shutdown 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)
self.process.terminate()
time.sleep(1) ## ADD A NEW LINE HERE
self.process.kill()
self.process.wait()
j'ai aussi un script python qui tourne sur mon mac en utilisant selenium pour faire des trucs en utilisant PhantomJS comme webdriver.
quand mon test est en cours d'exécution, il y a trois processus à noter sont ici:
$ 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
notez la deuxième colonne qui sont les numéros de processus, et la troisième qui est celle qui traite parent. Mon script de test est le parent. Il y a un processus de noeud qui a mon script de test comme parent, puis il y a un autre processus PhantomJS dont le parent est le noeud processus. Ne me demandez pas pourquoi il y a deux processus PhantomJS, je suppose que c'est juste comment il est conçu pour fonctionner?
de toute façon, dans mon mac moniteur d'activité, je peux voir ceci:
Notez le NIP 28090.
une fois que mon test a fini d'exécuter ceci, les processus traînent autour, tout comme vous aussi. Si je vérifie que les processus sont toujours en cours d'exécution, je peux voir:
$ 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
il me semble donc que driver.quit()
sort du noeud processus, celui avec le numéro de PID 28088, mais il laisse son enfant orphelin. Je ne sais pas si c'est intentionnel. Si ce n'est pas intentionnel, alors je pense qu'il n'y a pas de "bonne" façon de sortir de ce processus dans votre code.
par conséquent, j'utiliserais l'équivalent de kill -9 28090
juste après driver.quit()