对象类型

四大类型

  • Tag
  • NavigableString
  • BeautifulSoup
  • Comment

Tag

与XML或HTML文档内容中的tag一致

soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
type(tag)
# <class 'bs4.element.Tag'>

name

>>> tag.name
'b'

# 修改tag名字, 此操作会影响所有通过当前Beautiful Soup对象生成的HTML文档
>>> tag.name = "blockquote"
>>> tag
<blockquote class="boldest">Extremely bold</blockquote>

attributes

tag的属性的操作方法同字典, tag的属性可以被添加,删除或修改

>>> tag['class']
['boldest']

使用 . 操作, 获取所有属性

>>> tag.attrs
{'class': ['boldest']}
多值属性

在BeautifulSoup中, 多值属性返回类型是list

css_soup = BeautifulSoup('<p class="body strikeout"></p>')
css_soup.p['class']
# ["body", "strikeout"]

css_soup = BeautifulSoup('<p class="body"></p>')
css_soup.p['class']
# ["body"]

如果某个属性看起来好像有多个值,但在任何版本的HTML定义中都没有被定义为多值属性,那么Beautiful Soup会将这个属性作为字符串返回

id_soup = BeautifulSoup('<p id="my id"></p>')
id_soup.p['id']
# 'my id'

将tag转换成字符串时,多值属性会合并为一个值

rel_soup = BeautifulSoup('<p>Back to the <a rel="index">homepage</a></p>')
rel_soup.a['rel']
# ['index']
rel_soup.a['rel'] = ['index', 'contents']
print(rel_soup.p)
# <p>Back to the <a rel="index contents">homepage</a></p>

如果转换的文档是XML格式,那么tag中不包含多值属性

xml_soup = BeautifulSoup('<p class="body strikeout"></p>', 'xml')
xml_soup.p['class']
# u'body strikeout'

BeautifulSoup

BeautifulSoup 对象表示的是一个文档的全部内容. 大部分时候, 可以把它当作 Tag 对象,它支持 遍历文档树搜索文档树 中描述的大部分的方法.

因为 BeautifulSoup 对象并不是真正的HTML或XML的tag,所以它没有name和attribute属性. 但有时查看它的 .name 属性是很方便的, 所以 BeautifulSoup 对象包含了一个值为 "[document]" 的特殊属性 .name

>>> soup.name
'[document]'

Comment

文档注释

markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
soup = BeautifulSoup(markup)
comment = soup.b.string

>>> type(comment)
<class 'bs4.element.Comment'>

>>> comment
'Hey, buddy. Want to buy a used parser?'

Comment 对象是一个特殊类型的 NavigableString 对象, 当它出现在HTML文档中时, Comment 对象会使用特殊的格式输出

>>> print(soup.b.prettify())
<b>
 <!--Hey, buddy. Want to buy a used parser?-->
</b>

Beautiful Soup中定义的其它类型都可能会出现在XML的文档中: CData , ProcessingInstruction , Declaration , Doctype .与 Comment 对象类似,这些类都是 NavigableString 的子类,只是添加了一些额外的方法的字符串独享.下面是用CDATA来替代注释的例子:

from bs4 import CData
cdata = CData("A CDATA block")
comment.replace_with(cdata)

print(soup.b.prettify())
# <b>
#  <![CDATA[A CDATA block]]>
# </b>