继承beautifulsoup html解析器,获取类型错误

时间:2011-10-07 08:33:53

标签: python beautifulsoup

我使用beautifulsoup great html解析器编写了一个小包装器

最近我尝试改进代码,并在包装​​类中直接使用所有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__或{ {1}} ..)我只是想使用这个功能。

而不是子类化我尝试从类的__getstate__返回一个beautifulsoup对象,但__init__方法返回__init__

很高兴在这里提供任何帮助。

1 个答案:

答案 0 :(得分:1)

BeautifulSoup代码中没有发生错误。相反,您的IDLE无法检索并打印对象。请改为print str(e)


无论如何,在你的情况下继承BeautifulSoup可能不是最好的主意。你真的想继承所有的解析方法(比如convert_charrefhandle_pierror)吗?更糟糕的是,如果你覆盖了BeautifulSoup使用的东西,它可能会以难以找到的方式破解。

我不知道你的情况,但我建议preferring composition over inheritance(即在属性中有一个BeautifulSoup对象)。您可以轻松地(如果以一种轻微的hacky方式)公开这样的特定方法:

class Scrape(object):
    def __init__(self, ...):
        self.soup = ...
        ...
        self.find = self.soup.find