python - 子类化 beautifulsoup html 解析器,出现类型错误

标签 python beautifulsoup

我使用 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_charrefhandle_pierror)吗?更糟糕的是,如果您覆盖 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/

相关文章:

python - 按下按钮时有多个命令

python - while循环不更新值

python - 在 beautifulsoup4 中具有子元素的标签内提取文本节点

python - 如何获取</h3>和<br/>之间的文本值

python - 如何在模型对象中访问 Django 模型的 id?

python - bigquery.client.query()可以查看2个结果集吗?

python - 对基于文本的信息进行分类(即实现字符串内核)

python - 用 Beautiful Soup 抓取和循环元标签

python - 如何将 Beautiful Soup 输出保存到我​​的 SQLite 数据库中?

python - Beautifulsoup 未返回页面的完整 HTML