簡體   English   中英

為什么Selenium + Node + PhantomJS在Python腳本結束后仍然運行?

[英]Why Selenium + Node + PhantomJS still running after Python script ends?

我使用PhantomJS收集有關Html頁面的數據。 我的代碼是這樣的:

from selenium import webdriver

class PageElements():

    def __init__(self, url):
        self.driver = webdriver.PhantomJS()
        self.driver.get(url)
        self.elements, self.attribute_types = self._load_elements(self.driver)

    def _load_elements(self, self.driver)
        """"This is not relevant"""

因此,在我有時在IPython Notebook上執行代碼之后,要測試一下。 過了一會兒,我在我的活動監視器上得到了這個:

在此輸入圖像描述

還有這個:

在此輸入圖像描述

即使我添加了一個驅逐艦之后,這些過程仍然會運行:

def __del__(self):
    self.driver.close()    

怎么了? 我真的很感激“為什么會這樣”的回答,而不是“做這個”。 為什么我的驅逐艦不工作?

我打開了@forivall鏈接,看到了Selenium代碼。 PhantomJS webdriver有它自己的析構函數(因此使我的多余)。 他們為什么不在這種情況下工作?

__del__()在python中往往不可靠。 你不僅不知道何時會被召喚,你甚至不能保證它會被召喚。 try / finally構造,或(甚至更好)with-blocks(也稱為上下文管理器),更可靠。

也就是說,即使使用上下文管理器,我也有類似的問題。 phantomjs進程遍布整個地方。 我通過硒調用phantomjs如下:

from selenium import webdriver
from contextlib import closing
with closing(webdriver.PhantomJS()) as driver:
    do_stuff(driver)

contextlibclosing()函數確保無論發生什么事情都會調用其參數的close()方法,但事實證明, driver.close()雖然可用,卻是清理webdriver會話的錯誤方法。 driver.quit()是清理的正確方法。 因此,不要執行上述操作,請執行以下操作之一:

from selenium import webdriver
from contextlib import contextmanager

@contextmanager
def quitting(quitter):
    try:
        yield quitter
    finally:
        quitter.quit()

with quitting(webdriver.PhantomJS()) as driver:
    do_stuff(driver)

要么

from selenium import webdriver
driver = webdriver.PhantomJS()
try:
    do_stuff(driver)
finally:
    driver.quit()

(以上兩個片段相同)

感謝@ Richard對原始問題的評論,指向我.quit()

截至2016年7月,在討論此GitHub問題后 ,最佳解決方案是運行:

import signal

driver.service.process.send_signal(signal.SIGTERM)
driver.quit()

而不是driver.close() 只運行driver.quit()會殺死node進程,但不會殺死它產生的phantomjs子進程。

    self.driver = webdriver.PhantomJS()

這將創建一個Web瀏覽器,然后由Selenium用於運行測試。 每次Selenium運行時,它都會打開一個新的Web瀏覽器實例,而不是查看是否有可以重新使用的前一個實例。 如果在測試結束時不使用.close,則瀏覽器將繼續在后台運行。

如您所見,多次運行測試會使多個瀏覽器孤立。

這種情況與Python通常會自動銷毀的垃圾收集器有什么區別?

不同之處在於它 Python的域之外創建了一些東西:它正在創建一個新的操作系統級流程。 也許webdriver.PhantomJS應該有自己的__del__ ,它會自行關閉 也許這種行為應該更加強大,但這不是硒開發人員的設計決定,可能是因為大多數其他驅動程序都沒有無頭(因此很明顯窗戶是打開的)。

不幸的是, (或非官方)文檔都沒有很多澄清/最佳實踐。 (見下面關於__del__行為的評論)。


鏈接到源: phantomjs / webdriver.py remote / webdriver.py (superclass)

我也在努力解決同樣的問題,我從這個源鏈接 解決了它。

通過用self.process.send_signal(signal.SIGTERM)替換selenium / webdriver / phantomjs / service.py中的self.process.kill()

通過使用driver.quit()將在完成程序時終止所有phantomjs進程或使用CTR + C取消程序

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM