1

質問は一般的なものですが、スピナーで奇妙なエラーが発生しています。Spynner は、Python 用のステートフル Web ブラウザー モジュールです。それが機能するときは正常に機能しますが、ほとんどすべての実行でこれを言って失敗します-

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/spynner-2.16.dev0-py2.7.egg/spynner/browser.py", line 1651, in createRequest
    self.cookies,
AttributeError: 'Browser' object has no attribute 'cookies'
Segmentation fault (core dumped)

ここでの問題は、セグメンテーション違反であり、続行できません。

spynner のコードを見ると、Cookie 変数が実際には次の__init__()ように Browser クラスの関数で初期化されていることがわかります。

self.cookies = []

__init__()失敗すると、cookie 変数が表示されないため、実行されていないと実際に言っています。どうすればそれが可能になるのかわかりません。spynner モジュールに限定せずに、python オブジェクトがこのようなエラーでどのように失敗するかについて誰かが推測できますか?

編集:コンパクトに表示するためにすべてを1か所にまとめたわけではないことを除いて、ここにコードを貼り付けたはずです。もっと早くやるべきだったのですが、全体の構造と spynner のインスタンス化と使用方法を以下に示します。

# helper class to get url data
class C:
   def __init__(self):
       self.browser = spynner.Browser()

   def get_data(self, url):
       try:
           self.browser.load(url)
           return self.browser.html
       except:
           raise

# class that does other stuff among saving url data to disk
class B:
    def save_url_to_disk(self, url):
        urlObj = C()
        html = urlObj.get_data(url)
        # do stuff with html


# class that drives everything
class A:
    def do_stuff_and_save_url_data(self, url):
       fileObj = B()
       fileObj.save_url_to_disk(url)

driver = A()
# call this function for multiple URLs.
driver.do_stuff_and_save_url_data(url)

私がそれを実行する方法は---

# xvfb-run python myfile.py

セグメンテーション違反は、おそらく私が行っている別のものです。私が使用している xvfb が適切に処理されていないためでしょうか? 私にはまだ分かりません。私はPythonに比較的慣れていないことに言及する必要があります。

「 http://www.google.com 」と言って上記のコードを実行すると、1回おきにsegfaultが発生することに気付きました。

4

1 に答える 1

0

のコード ブロックはdo_stuff_and_save_url_data()参照を使用しません。このself関数
の実行は に依存しませんdriver

のコード ブロックsave_url_to_disk()も参照を使用しません。この 2 番目のself関数
の実行はオブジェクトに依存しませんfileObj

のコード ブロックのみが参照をget_data()使用しますself。より正確には参照を使用しself.browserます。そのため、その実行と結果はclassのインスタンス
の属性に依存します。この属性は、実際には、クラスの名前が付けられたブラウザ インスタンスです。browserurlObjCbrowserspynner.Browser

最後に、によって出力されたデータだけで「html を処理」spynner.Browser().htmlします。と の作成は、決して必須ではdriverありfileObjません。

.

別のポイントは
、命令driver.do_stuff_and_save_url_data(url)が実行されると
、メソッドdriver.do_stuff_and_save_url_data(url)が最初に作成され、次に実行され、最後に「破棄」される (または、より正確には RAM のどこかで忘れられる) ことです。これは、メソッドがどの識別子にも割り当てられていないためです。

次に、fileObjfunction のローカル名前空間に属する識別子である identifierも失われます。これは、 classdriver.do_stuff_and_save_url_data()のインスタンスfileObjBも、割り当てられた識別子が生きていないため、後で使用するために失われることを意味します。

についても同じですsave_url_to_disk()
メソッドの作成と実行後、browser のインスタンス ( によって作成されたオブジェクト) を含むclassfileObj.save_url_to_disk(url)のオブジェクトurlObjが失われます。作成されたブラウザとそのすべてのデータが失われます。Cspynner.Browser()

do_stuff_and_save_url_data()これは、を実行するたびにブラウザ インスタンスが破棄されるためではないかと思いsave_url_to_disk()ます。また、不審な呼び出しの前に Cookie 情報が破棄されないのではないかと思います。

.

したがって、私の意見では、あなたのコードはクラスの 2 つの定義に 2 つの関数を埋め込むだけでAありB、それらはメソッドとしてではなく、関数と見なされるものとして使用されます。

1/ 良いコーディング パターンではないと思います。単純な関数のみが必要な場合は、それらをクラスの外に記述する必要があります。

2/問題は、操作が関数によってトリガーされる場合、メソッドのマントルがある場合でも、これらの関数がアクティブ化されるたびに新しいブラウザーが作成されることです。

で定義されたブラウザによって提供されるデータでこれらの関数を動作させたいと言うでしょうspynny.Browser()
そのため、今のようにクラスに埋め込まれた関数ではなく、ブラウザーの安定したインスタンスにアタッチされた実際のメソッドであってはならないと思います。これが、データとデータを処理するツールを同じ名前空間に保持するオブジェクトの目的です。

-

.

そうは言っても、私は個人的に次のように書きます。

class C(spynner.Browser):
   def __init__(self):
       spynner.Browser.__init__(self)

   def get_data(self, url):
       try:
           self.html = self.load(url).html
       except:
           raise

    # method that does other stuff among saving url data to disk
    def save_url_to_disk(self, url):
        get_data(url)
        # do stuff with self.html

    # method that drives everything
    def do_stuff_and_save_url_data(self, url):
        self.save_url_to_disk(url)


driver = C()
driver.do_stuff_and_save_url_data(url)

しかし、私はあなたのすべての考慮事項を十分に理解しているかどうか確信が持てず、あなたの投稿を読む前にスピナーを知らなかったことを警告します. 私が書いたことはすべて、実際の問題に比べてばかげている可能性があります。私の投稿に批評家の目を向けてください。

于 2013-12-11T15:05:49.880 に答える