我遇到了一个与spynner的奇怪错误,虽然问题是一般的问题。 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的代码我发现cookies变量实际上是在Browser类的__init__()
函数中初始化的,如下所示:
self.cookies = []
现在失败了它真的说__init__()
没有运行,因为它没有看到cookie变量。我不明白这是怎么可能的。在不限制spynner模块的情况下,有人可以冒险猜测python对象如何失败并出现这样的错误吗?
# 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'时,我每隔一段时间就得到一次段错误。
答案 0 :(得分:0)
do_stuff_and_save_url_data()
的代码块不使用引用self
:
那么这个函数的执行不依赖于driver
。
save_url_to_disk()
的代码块也不使用引用self
:
那么第二个函数的执行不依赖于对象fileObj
。
只有get_data()
的代码块使用引用self
,更准确地说是参考self.browser
:
所以它的执行和结果取决于来自类browser
的实例urlObj
的属性C
。该属性实际上是browser
类的名为spynner.Browser
的浏览器实例。
最后,您只需使用spynner.Browser().html
输出的数据“使用html执行操作”。 driver
和fileObj
的创建不是强制性的。
另一点是,
当执行指令driver.do_stuff_and_save_url_data(url)
时,
首先创建方法driver.do_stuff_and_save_url_data(url)
,然后执行,最后“销毁”(或者更确切地说忘记在RAM中的某个地方),因为它尚未被分配给任何标识符。
然后标识符fileObj
(属于函数driver.do_stuff_and_save_url_data()
的本地名称空间的标识符)也丢失,这意味着类{{的实例 fileObj 由于没有更多的指定标识符存活,1}}也因使用不当而丢失。
B
的情况相同:
在创建和执行方法save_url_to_disk()
之后,类fileObj.save_url_to_disk(url)
的对象 urlObj ,其中包含一个浏览器实例(由C
创建的对象),丢失了:创建的浏览器及其所有数据都丢失了。
我想知道这是不是因为每次执行spynner.Browser()
和do_stuff_and_save_url_data()
后浏览器实例的破坏都会导致在不可告人的呼叫之前不会销毁cookie信息。
因此,在我看来,您的代码只在两个类save_url_to_disk()
和A
的定义中嵌入了两个函数,它们被用作函数,而不是方法。
1 /我认为这不是一个好的编码模式。当只需要普通函数时,它们必须在任何类之外编写。
2 /问题是如果操作是由函数触发的,每次激活这些函数时都会创建一个新的浏览器,即使它们具有方法。您会告诉我您希望这些功能与B
定义的浏览器提供的数据一起使用
这就是为什么我认为它们不能像现在一样嵌入到类中的函数,而是附加到稳定的浏览器实例的实际方法。这是对象的目标,即在数据库和处理数据的工具中保持相同的名称空间。
-
所有这一切,我会亲自写道:
spynny.Browser()
但我不确定你的所有考虑因素都不好,我警告说在阅读你的帖子之前我并不认识spynner。我写的所有内容都可能比你真正的问题更愚蠢。请关注我的帖子。