3

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には独自のデストラクタがあります (したがって、私のものは冗長になります)。この場合、なぜ彼らは働いていないのですか?

4

5 に答える 5

3

__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)

contextlibの関数は、その引数のメソッドが何が起こってもclosing()確実に呼び出されるようにします。 が正しい洗い方です。したがって、上記の代わりに、次のいずれかを実行します。close()driver.close()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()

(上記の 2 つのスニペットは同等です)

クレジットは、元の質問に対する@Richardのコメントにあり、私を.quit().

于 2015-03-05T19:09:27.767 に答える
0

この場合と、Python が通常ガベージ コレクタで自動的に破棄するオブジェクトとの違いは何ですか?

違いは、Python のドメイン外に何かを作成していることです。つまり、新しい OS レベルのプロセスを作成しています。おそらく、それ自体をシャットダウンするwebdriver.PhantomJS独自のものが必要です__del__おそらく、動作はより堅牢になるはずですが、おそらく他のほとんどのドライバーがヘッドレスではないため、セレン開発者が行った設計上の決定ではありません (したがって、ウィンドウが開いていることは明らかです)。

残念ながら、セレン (または非公式) のドキュメントには、これに関する明確化/ベスト プラクティスはあまりありません。(動作に関する以下のコメントを参照してください__del__)。


ソースへのリンク: phantomjs/webdriver.py remote/webdriver.py (スーパークラス)

于 2013-09-25T17:57:32.273 に答える