我使用 beautifulsoup 编写了一个小的包装器 html 解析器
最近我尝试改进代码并使所有 beautifulsoup 方法直接在包装类中可用(而不是通过类属性),我认为子类化 beautifulsoup 解析器将是实现这一目标的最佳方式。
这是类:
class ScrapeInputError(Exception):pass
from BeautifulSoup import BeautifulSoup
class Scrape(BeautifulSoup):
"""base class to be subclassed
basically a subclassed BeautifulSoup wrapper that providers
basic url fetching with urllib2
and the basic html parsing with beautifulsoup
and some basic cleaning of head,scripts etc'"""
def __init__(self,file):
self._file = file
#very basic input validation
import re
if not re.search(r"^http://",self._file):
raise ScrapeInputError,"please enter a url that starts with http://"
import urllib2
#from BeautifulSoup import BeautifulSoup
self._page = urllib2.urlopen(self._file) #fetching the page
BeautifulSoup.__init__(self,self._page)
#self._soup = BeautifulSoup(self._page) #calling the html parser
这样我就可以开始上课了
x = Scrape("http://someurl.com")
并能够使用 x.elem 或 x.find 遍历树
这对某些 beautifulsoup 方法(见上文)非常有效,但对其他方法却失败了——那些使用像“for e in x:”这样的迭代器的方法
错误信息:
Traceback (most recent call last):
File "<pyshell#86>", line 2, in <module>
print e
File "C:\Python27\lib\idlelib\rpc.py", line 595, in __call__
value = self.sockio.remotecall(self.oid, self.name, args, kwargs)
File "C:\Python27\lib\idlelib\rpc.py", line 210, in remotecall
seq = self.asynccall(oid, methodname, args, kwargs)
File "C:\Python27\lib\idlelib\rpc.py", line 225, in asynccall
self.putmessage((seq, request))
File "C:\Python27\lib\idlelib\rpc.py", line 324, in putmessage
s = pickle.dumps(message)
File "C:\Python27\lib\copy_reg.py", line 77, in _reduce_ex
raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
我研究了错误消息但找不到任何我可以使用的东西 - 因为我不想玩 BeautifulSoup 的内部植入(老实说我不知道或不理解 __slot__
或 __getstate__
..) 我只想使用该功能。
我尝试从类的 __init__
返回一个 beautifulsoup 对象,而不是子类化,但是 __init__
方法返回 None
很高兴在这里得到任何帮助。
最佳答案
BeautifulSoup 代码中没有发生错误。相反,您的 IDLE 无法检索和打印该对象。请尝试使用 print str(e)
。
无论如何,在您的情况下子类化 BeautifulSoup 可能不是最好的主意。您真的要继承所有的解析方法(如 convert_charref
、handle_pi
或 error
)吗?更糟糕的是,如果您覆盖 BeautifulSoup 使用的某些东西,它可能会以一种难以找到的方式中断。
不知道你的情况,但是我建议preferring composition over inheritance (即在属性中有一个 BeautifulSoup 对象)。你可以很容易地(如果以一种有点怪异的方式)公开特定的方法,就像这样:
class Scrape(object):
def __init__(self, ...):
self.soup = ...
...
self.find = self.soup.find
关于python - 子类化 beautifulsoup html 解析器,出现类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7684794/