Подтвердить что ты не робот

Как правильно остановить выполнение phantomjs

Я начал и закрою phantomjs в Python со следующим

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

еще после завершения выполнения script я все еще нахожу экземпляр phantomjs в своем мониторе активности Mac. И фактически каждый раз, когда я запускаю script, создается новый процесс phantomjs.

Как закрыть драйвер?

4b9b3361

Ответ 1

Метод .close() не гарантирует освобождение всех ресурсов, связанных с экземпляром драйвера. Обратите внимание, что эти ресурсы включают, но могут не ограничиваться, исполняемый файл драйвера (PhantomJS, в данном случае). Метод .quit() предназначен для освобождения всех ресурсов драйвера, включая выход из исполняемого процесса.

Ответ 2

По состоянию на июль 2016 года driver.close() и driver.quit() мне не хватало. Это убило процесс node, но не дочерний процесс phantomjs, который он породил.

После обсуждения этой проблемы GitHub единственным решением, которое сработало для меня, было выполнение:

import signal

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

Ответ 3

Обратите внимание, что это, очевидно, вызовет проблемы, если у вас есть несколько потоков/процессов, запускающих PhantomJS на вашем компьютере.

Я видел, как несколько человек борются с одной и той же проблемой, но для меня простейшим обходным/хаком было выполнение следующего из командной строки через Python ПОСЛЕ того, как вы вызывали driver.close() или driver.quit():

pgrep phantomjs | xargs kill

Ответ 4

У меня была аналогичная проблема на Windows-машине. Мне не повезло ни с кем

driver.close()

или

driver.quit()

фактически закрывается окно PhantomJS, но когда я использовал оба, окно PhantomJS окончательно закрылось и вышло должным образом.

driver.close()
driver.quit()

Ответ 5

driver.quit() не работал у меня в Windows 10, поэтому в итоге я добавил следующую строку сразу после вызова driver.close():

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

где

/f = force
/im = by image name

И поскольку это решение только для Windows, может быть разумным только выполнить, если os.name == 'nt'

Ответ 6

Какую ОС вы используете? Я думаю, что это соответствует случаю следующего, если вы используете ОС POSIX.

Я создаю запрос на pull, но он отклоняется. https://github.com/SeleniumHQ/selenium/pull/2244

Но я думаю, что это правильно. Поэтому я выпустил вопрос. https://github.com/SeleniumHQ/selenium/issues/2272

Основной причиной этой проблемы является то, что конечный метод фантомов драйвера призрака неверен. Он не использует API завершения призрачного драйвера phantomjs в конце.

В случае phantomjs, который вы установили в npm в Linux или OSX, Селен вызывает Popen для phantomjs, а phantomjs вызывается для lib/phantomjs.js. В это время селен является родительским, phantomjs является дочерним, а lib/phantomjs.js является внуком.

Вы вызываете quit() в parent (selenium), он отправляет SIGTERM в child (phantomjs). и ребенок (phantomjs) отправляет SIGTERM внуку (lib/phantomjs.js) в дочернюю функцию обработчика SIGTERM.

Внучка будет зомби, когда родитель отправит SIGKILL к ребенку до того, как ребенок отправит SIGTERM внуку.

Этот запрос на извлечение ttps://github.com/SeleniumHQ/selenium/pull/2244 может быть завершен с использованием режима отключения призрачного драйвера 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.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()

Ответ 7

У меня также есть python script, работающий на моем mac, используя селен, чтобы сделать некоторые вещи, используя 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

Обратите внимание на второй столбец, который является номерами процессов, а третий - процессом parent. Мой тест script является родительским. Существует процесс node, который имеет мой тест script как родительский, тогда есть еще один процесс PhantomJS, родителем которого является процесс node. Не спрашивайте меня, почему существуют два процесса PhantomJS, я думаю, именно так оно и работает?

Во всяком случае, в моем мониторе активности в моей среде я вижу это:

введите описание изображения здесь

Обратите внимание на номер 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() выходит из процесса node, с номером PID 28088, но оставляет своего ребенка сиротой. Я не знаю, намеренно ли это. Если это не преднамеренно, я думаю, что нет никакого "правильного" способа выхода из этого процесса в вашем коде.

Поэтому я бы использовал ваш эквивалент языка kill -9 28090, сразу после driver.quit()