美丽的汤错误:'<类的bs4.element.Tag'>'对象有没有属性'的内容“? [英] Beautiful Soup Error: '<class 'bs4.element.Tag'>' object has no attribute 'contents'?

查看:4128
本文介绍了美丽的汤错误:'<类的bs4.element.Tag'>'对象有没有属性'的内容“?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写提取出内容的文章,并移除任何不必要的东西如一个脚本。脚本和造型。美丽的汤把某以下异常:

 '<类的bs4.element.Tag'>'对象有没有属性'内容'

下面是修正功能的code(元素是包含网页内容中的HTML元素):

 高清修剪(元):
    elements_to_remove =(脚本,风格,链接,形式,对象,IFRAME)
    因为我在elements_to_remove:
        remove_all_elements(单元,I)    attributes_to_remove =(类,ID,风格)
    因为我在attributes_to_remove:
        remove_all_attributes(单元,I)    remove_all_comments(元)    #删除具有比p元素更多的非p元素的div
    在element.find_all格('DIV'):
        P = LEN(div.find_all('P'))
        IMG = LEN(div.find_all('IMG'))
        LI = LEN(div.find_all(礼))
        A = LEN(div.find_all('A'))        如果p == 0或IMG> p或立GT; p或一>电话号码:
            div.decompose()

在堆栈跟踪来看,问题似乎后立即从这种方法来for语句:

 #删除具有比p元素更多的非p元素的div
    在element.find_all格('DIV'):
        P = LEN(div.find_all('P'))#< - div.find_all('P')

我不明白为什么bs4.element.Tag这个实例没有属性内容?我尝试过了一个实际的网页和元素充满了P公司和IMG的...

这里的回溯(这是一个Django项目我工作的一部分):

 环境:
请求方法:POST
请求URL:http://本地主机:8000 /读/添加/Django的版本:1.4.1
Python版本:2.7.3
安装的应用程序:
('django.contrib.auth',
 django.contrib.contenttypes',
 django.contrib.sessions',
 django.contrib.sites',
 django.contrib.messages',
 django.contrib.staticfiles',
 '家',
 '帐户',
 '读',
 '评论')
安装中间件:
(django.middleware.common.CommonMiddleware',
 django.contrib.sessions.middleware.SessionMiddleware',
 django.middleware.csrf.CsrfViewMiddleware',
 django.contrib.auth.middleware.AuthenticationMiddleware',
 django.contrib.messages.middleware.MessageMiddleware')
追溯:
文件/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/django/core/handlers/base.py在get_response
  111.响应=回调(请求,* callback_args,** callback_kwargs)
文件/home/marco/sandra/read/views.py中加
  24. Article.objects.create_article(request.user,URL)
文件/home/marco/sandra/read/models.py在create_article
  11.标题,内容= logic.process_html(web_page.read())
文件/home/marco/sandra/read/logic.py在process_html
  7.汤= htmlbarber.give_haircut(BeautifulSoup(html_ code,'html5lib'))
文件/home/marco/sandra/read/htmlbarber/__init__.py在give_haircut
  45. scissor.trim(元)
文件/home/marco/sandra/read/htmlbarber/scissor.py,在装饰
  35. P = LEN(div.find_all('P'))
文件/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py在find_all
  1128回self._find_all(姓名,ATTRS,文字,极限,发电机,** kwargs)
文件/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py在_find_all
  413回[在发电机元素元素
在后代文件/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py
  1140.如果没有LEN(self.contents):
文件/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py在__getattr__
  924.'%s'的对象有没有属性'%s'%(自我.__ class__,标签))异常类型:AttributeError的AT /读/添加/
异常值:'<类的bs4.element.Tag'>'对象有没有属性'内容'

下面是remove_all_ *函数的源$ C ​​$ C:

 高清remove_all_elements(element_to_clean,unwanted_element_name):
    在element_to_clean.find_all(unwanted_element_name)to_remove:
        to_remove.decompose()高清remove_all_attributes(element_to_clean,unwanted_attribute_name):
    对于在[element_to_clean] + element_to_clean.find_all to_inspect():
        尝试:
            德尔to_inspect [unwanted_attribute_name]
        除了KeyError异常:
            通过高清remove_all_comments(element_to_clean):
    在element_to_clean.find_all评论(文文的λ=:isinstance(文字,评论)):
        comment.extract()


解决方案

我认为问题是,在 remove_all_elements 或者在code别的地方要删除一些广告代码的内容属性。

它看起来像当你调用 to_remove.decompose这种情况正在发生()。下面是该方法的来源:

  DEF分解(个体经营):
    递归破坏这棵树的内容
    self.extract()
    I =自
    而我是不是无:
        接下来= i.next_element
        我.__字典__。清除()
        我旁边=

下面是如果手动调用这个函数会发生什么:

 >>汤= BeautifulSoup('< D​​IV>< P>喜< / P>< / DIV>')
>>> D0 = soup.find_all('DIV')[0]
>>> D0
< D​​IV>< P>喜< / P>< / DIV>
>>> d0.decompose()
>>> D0
回溯(最近通话最后一个):
...
回溯(最近通话最后一个):
AttributeError的:'<类的bs4.element.Tag'>'对象有没有属性'内容'

看来,一旦你叫分解你必须永远不会试图再次使用该标签的标签。我不太肯定这虽然发生。

有一件事我会尝试检查是 LEN(元素.__ dict__)GT; 0 在任何时候你的修剪()功能。

I'm writing a script that extracts the content out of an article and removes any unnecessary stuff eg. scripts and styling. Beautiful Soup keeps raising the following exception:

'<class 'bs4.element.Tag'>' object has no attribute 'contents'

Here's the code of the trim function (element is the HTML element that contains the content of the webpage):

def trim(element):
    elements_to_remove = ('script', 'style', 'link', 'form', 'object', 'iframe')
    for i in elements_to_remove:
        remove_all_elements(element, i)

    attributes_to_remove = ('class', 'id', 'style')
    for i in attributes_to_remove:
        remove_all_attributes(element, i)

    remove_all_comments(element)

    # Remove divs that have more non-p elements than p elements
    for div in element.find_all('div'):
        p = len(div.find_all('p'))
        img = len(div.find_all('img'))
        li = len(div.find_all('li'))
        a = len(div.find_all('a'))

        if p == 0 or img > p or li > p or a > p:
            div.decompose()

Looking at the stack trace, the problem seems to be coming from this method right after the for statement:

    # Remove divs that have more non-p elements than p elements
    for div in element.find_all('div'):
        p = len(div.find_all('p')) # <-- div.find_all('p')

I don't get why this instance of bs4.element.Tag doesn't have the attribute 'contents'? I tried it out on an actual webpage and the element was full of p's and img's...

Here's the traceback (This is part of a Django project I'm working on):

Environment:


Request Method: POST
Request URL: http://localhost:8000/read/add/

Django Version: 1.4.1
Python Version: 2.7.3
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'home',
 'account',
 'read',
 'review')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/home/marco/sandra/read/views.py" in add
  24.             Article.objects.create_article(request.user, url)
File "/home/marco/sandra/read/models.py" in create_article
  11.         title, content = logic.process_html(web_page.read())
File "/home/marco/sandra/read/logic.py" in process_html
  7.     soup = htmlbarber.give_haircut(BeautifulSoup(html_code, 'html5lib'))
File "/home/marco/sandra/read/htmlbarber/__init__.py" in give_haircut
  45.     scissor.trim(element)
File "/home/marco/sandra/read/htmlbarber/scissor.py" in trim
  35.         p = len(div.find_all('p'))
File "/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py" in find_all
  1128.         return self._find_all(name, attrs, text, limit, generator, **kwargs)
File "/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py" in _find_all
  413.                 return [element for element in generator
File "/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py" in descendants
  1140.         if not len(self.contents):
File "/home/marco/.virtualenvs/sandra/local/lib/python2.7/site-packages/bs4/element.py" in __getattr__
  924.             "'%s' object has no attribute '%s'" % (self.__class__, tag))

Exception Type: AttributeError at /read/add/
Exception Value: '<class 'bs4.element.Tag'>' object has no attribute 'contents'

Here's the source code of remove_all_* functions:

def remove_all_elements(element_to_clean, unwanted_element_name):
    for to_remove in element_to_clean.find_all(unwanted_element_name):
        to_remove.decompose()

def remove_all_attributes(element_to_clean, unwanted_attribute_name):
    for to_inspect in [element_to_clean] + element_to_clean.find_all():
        try:
            del to_inspect[unwanted_attribute_name]
        except KeyError:
            pass

def remove_all_comments(element_to_clean):
    for comment in element_to_clean.find_all(text=lambda text:isinstance(text, Comment)):
        comment.extract()

解决方案

I think the problem is that in remove_all_elements or somewhere else in your code you are deleting the contents attribute of some of your tags.

It looks like this is happening when you call to_remove.decompose(). Here is the source for that method:

def decompose(self):
    """Recursively destroys the contents of this tree."""
    self.extract()
    i = self
    while i is not None:
        next = i.next_element
        i.__dict__.clear()
        i = next

Here is what happens if you call this function manually:

>> soup = BeautifulSoup('<div><p>hi</p></div>')
>>> d0 = soup.find_all('div')[0]
>>> d0
<div><p>hi</p></div>
>>> d0.decompose()
>>> d0
Traceback (most recent call last):
...
Traceback (most recent call last):
AttributeError: '<class 'bs4.element.Tag'>' object has no attribute 'contents'

It appears that once you have called decompose on a tag you must never attempt to use that tag again. I'm not quite sure where this is happening though.

One thing I would try checking is that len(element.__dict__) > 0 at all times in your trim() function.

这篇关于美丽的汤错误:'&LT;类的bs4.element.Tag'&GT;'对象有没有属性'的内容“?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆