一、四大对象种类
1、简介
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:
对象名 | 描述 |
---|---|
BeautifulSoup | 文档自身:表示的是一个文档的全部内容 |
Tag | 标签对:Tag对象与XML或HTML原生文档中的tag相同,即标签对 |
NavigableString | 标签值:标签对中的字符串 |
Comment | 注释:文档的注释部分 |
-
Tag(标签):Tag对象表示HTML或XML文档中的标签,它包含了标签的名称、属性和内容。您可以通过Tag对象访问标签的属性和内容,以及对标签进行操作和修改。
-
NavigableString(可导航字符串):NavigableString对象表示标签内的文本内容,它是标签内文本的容器。您可以通过NavigableString对象访问文本内容,进行文本处理和操作。
-
BeautifulSoup(Beautiful Soup对象):BeautifulSoup对象表示整个文档,它是文档的顶层容器,包含了整个文档的结构信息。您可以通过BeautifulSoup对象来遍历文档树、搜索元素以及提取数据。
-
Comment(注释):Comment对象表示文档中的注释内容,它用于表示HTML或XML文档中的注释部分。您可以通过Comment对象访问注释内容。
这些对象的组合和结构构成了Beautiful Soup库对文档的解析表示,使用户能够方便地操作和提取文档中的数据。在使用Beautiful Soup进行网页数据提取和处理时,您将会频繁地与这些对象打交道。
2、详细介绍
以下是它们的详细介绍以及附带的代码解释:
(1)BeautifulSoup(Beautiful Soup对象)
- BeautifulSoup对象表示整个文档,是文档的顶层容器,包含了整个文档的结构信息。
- 您可以通过BeautifulSoup对象来遍历文档树、搜索元素以及提取数据。
# 示例代码
from bs4 import BeautifulSoup
# 创建一个简单的HTML文档
html_doc = "<html><body><p>Welcome to Beautiful Soup</p></body></html>"
# 使用BeautifulSoup解析HTML文档
soup = BeautifulSoup(html_doc, 'html.parser')
# 打印整个文档
print(soup.prettify())
(2)Tag(标签)
- Tag对象代表HTML或XML文档中的标签,包含标签的名称、属性和内容。
- 在BeautifulSoup中可以利用beautifulsoup对象下面的方法返回这些标签数据,这些标签数据称为Tag对象(Tag对象指的是整个标签对:从开始标签到结束标签,包括里面的嵌套标签)
① 获取Tag对象
从一个beautifulsoup对象中获取指定的Tag对象,可以使用:beautifulsoup对象.标签名
注:这种方法返回的Tag对象是所有内容中第一个符合要求的标签
即:文档中存在多个同名的标签时,使用"beautifulsoup对象.标签名"返回的始终是第一个符合的标签
示例
from bs4 import BeautifulSoup # 导入bs4库
htmlData = """
<html>
<head>
<title>The Dormouse's story</title>
</head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">
<a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
</p>
<p class="story">they lived at the bottom of a well</p>
</body>
</html>
"""
soup = BeautifulSoup(htmlData, "lxml")
# 获取head标签
headTag = soup.head
print("获取到的heade标签为:", headTag)
# 获取title标签
titleTag = soup.title
print("获取到的title标签为:", titleTag)
# 获取a标签
aTag = soup.a
print("获取到的a标签为:", aTag)
# 获取p标签
pTag = soup.p
print("获取到的p标签为:", pTag)
print("获取到的p标签类型为:", type(pTag))
"""
获取到的header标签为: <head>
<title>The Dormouse's story</title>
</head>
获取到的title标签为: <title>The Dormouse's story</title>
获取到的a标签为: <a class="sister" href="http://example.com/elsie" id="link1">Elsie</a>
获取到的p标签为: <p class="title"><b>The Dormouse's story</b></p>
获取到的p标签类型为: <class 'bs4.element.Tag'>
"""
② tag对象的name属性
-
每个tag都有自己的名字,其成为tag对象的name属性(name属性:标签对的名称)
-
获取一个Tag对象的name属性,可以使用:Tag对象.name
示例
from bs4 import BeautifulSoup #导入bs4库
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html,"lxml") #指定解析器
soup_tag_name = soup.name #获取整个BeautifulSoup对象的name属性
title_tag_name = soup.title.name #获取title标签对象的name属性
head_tag_name = soup.head.name #获取head标签对象的name属性
a_tag = soup.a #获取a标签对象
a_tag_name = a_tag.name #获取a标签对象的name属性
print("整个BeautifulSoup对象的name属性为:",soup_tag_name)
print("title标签对象的name属性为:",title_tag_name)
print("header标签对象的name属性为:",head_tag_name)
print("a标签对象为:",a_tag)
print("a标签对象的name属性为:",a_tag_name)
"""
整个BeautifulSoup对象的name属性为: [document]
title标签对象的name属性为: title
header标签对象的name属性为: head
a标签对象为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
a标签对象的name属性为: a
"""
③ tag对象的attrs属性
-
attrs属性:指的是一个标签的属性
- 一个标签的属性一般是由键值对组成,属性名=值
<p class="story">...</p>
,其中的class="story"就是标签的属性
-
一个标签可能有很多个属性
-
获取一个Tag对象的attrs属性,可以使用:Tag对象.attrs
-
使用Tag对象的attrs属性可以把标签对的属性以字典形式返回
- Tag对象无属性时返回的是一个空字典
示例
from bs4 import BeautifulSoup #导入bs4库
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html,"lxml") #指定解析器
soup_tag_attrs = soup.attrs #获取整个BeautifulSoup对象的attrs属性
title_tag_attrs = soup.title.attrs #获取title Tag对象的attrs属性
head_tag_attrs = soup.head.attrs #获取head Tag对象的attrs属性
a_tag = soup.a #获取a标签的Tag对象
a_tag_attrs = a_tag.attrs #获取a Tag对象的attrs属性
print("BeautifulSoup对象的attrs属性为:",soup_tag_attrs)
print("titlea标签的Tag对象的attrs属性为:",title_tag_attrs)
print("heada标签的Tag对象的attrs属性为:",head_tag_attrs)
print("a标签的Tag对象为:",a_tag)
print("a标签的Tag对象的attrs属性为:",a_tag_attrs)
"""
BeautifulSoup对象的attrs属性为: {}
titlea标签的Tag对象的attrs属性为: {}
heada标签的Tag对象的attrs属性为: {}
a标签的Tag对象为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
a标签的Tag对象的attrs属性为: {'id': 'link1', 'href': 'http://example.com/elsie', 'class': ['sister']}
"""
如果想要单独获取某个属性具体的值时,可以使用下面三种方法:
(1)使用字典方法:字典索引、字典get()方法
(2)使用tag对象的get()方法:soup对象.标签名.get(属性名)
(3)使用soup对象.标签名.属性名(键名)
④ 多值属性
-
一般情况下,对于标签的属性都是以键值对存在的(一键一值,键=值)。但是某些属性可以存在多个值的情况(一键多值)。这种情况就称为多值属性
-
最常见的多值的属性是 class (一个tag可以有多个CSS的class)。还有一些属性rel , rev , accept-charset , headers , accesskey。在Beautiful Soup中多值属性的返回类型是列表
from bs4 import BeautifulSoup
soup = BeautifulSoup('<p class="body strikeout"></p>',"lxml")
print("p标签的tag对象为",soup.p)
print("p标签的tag对象的属性为",soup.p.attrs) #其值为一个字典
print("p标签的class属性为",soup.p.attrs.get("class"))
css_soup = BeautifulSoup('<p class="body"></p>',"lxml")
print(css_soup.p['class'])
"""
p标签的tag对象为 <p class="body strikeout"></p>
p标签的tag对象的属性为 {'class': ['body', 'strikeout']}
p标签的class属性为 ['body', 'strikeout']
['body']
"""
特别注意之处
from bs4 import BeautifulSoup
# 如果某个属性看起来好像有多个值,但在任何版本的HTML定义中都没有被定义为多值属性,那么Beautiful Soup会将这个属性作为字符串返回
css_soup = BeautifulSoup('<p id="my id"></p>',"lxml")
print(css_soup.p['id']) # id是一对第一,并非多值属性
#如果转换的文档是XML格式,那么tag中不包含多值属性
xml_soup = BeautifulSoup('<p class="body strikeout"></p>', 'xml')
print(xml_soup.p['class'])
"""
my id
body strikeout
"""
⑤ 获取标签对象的文本内容
在Beautiful Soup中,.string
和.strings
是用于获取标签对象文本内容的两个不同属性或方法。
-
.string
:.string
是用于获取标签对象中的单个字符串内容的属性。如果标签对象只包含单个字符串,那么使用.string
可以直接获取这个字符串内容。- 如果标签对象包含多个字符串,但这些字符串之间没有标签或其他元素分隔,
.string
会返回这些字符串合并后的内容。 - 如果标签对象包含子标签,
.string
会返回None
,因为这种情况下标签对象不是单个字符串。
-
.strings
:.strings
是用于获取标签对象中所有字符串内容的生成器(generator)方法。它会返回一个生成器对象,可以用于迭代获取标签对象中的所有字符串内容。- 如果标签对象包含多个字符串,
.strings
会将这些字符串分别作为独立的元素返回。 - 如果标签对象包含子标签,
.strings
会忽略子标签,只返回直系子元素中的字符串内容。
下面是一个示例代码,演示了.string
和.strings
的用法:
from bs4 import BeautifulSoup
# 创建一个包含多个字符串的标签对象
html_doc = "<html><body><p>Welcome to <b>Beautiful Soup</b></p></body></html>"
soup = BeautifulSoup(html_doc, 'html.parser')
# 使用.string获取单个字符串内容
p_tag = soup.find('p')
single_string = p_tag.string
print(single_string)
# 使用.strings获取所有字符串内容
all_strings = list(p_tag.strings)
print(all_strings)
# None
# ['Welcome to ', 'Beautiful Soup']
在这个示例中,我们首先创建了一个包含多个字符串的标签对象。然后,我们分别使用.string
和.strings
来获取其中的字符串内容。.string
返回了标签对象中的单个字符串内容,而.strings
返回了所有字符串内容的生成器对象。
(3)NavigableString(可导航字符串)
- NavigableString对象表示标签内的文本内容,是标签内文本的容器。
- 您可以通过NavigableString对象访问文本内容,进行文本处理和操作。
# 示例代码
from bs4 import BeautifulSoup
# 创建一个简单的HTML文档
html_doc = "<html><body><p>Welcome to <strong>Beautiful Soup</strong></p></body></html>"
# 使用BeautifulSoup解析HTML文档
soup = BeautifulSoup(html_doc, 'html.parser')
# 获取<p>标签内的文本
p_tag = soup.find('p')
text_content = p_tag.string
# 打印文本内容
print(text_content) # 输出:'Welcome to '
# 修改文本内容
text_content.replace_with('Welcome to the Beautiful Soup Library')
# 打印修改后的文本内容
print(p_tag.text) # 输出:'Welcome to the Beautiful Soup Library'
(4)Comment(注释)
- Comment对象表示文档中的注释内容,用于表示HTML或XML文档中的注释部分。
- 您可以通过Comment对象访问注释内容。
# 示例代码
from bs4 import BeautifulSoup
# 创建一个包含注释的HTML文档
html_doc = "<html><body><!-- This is a comment --><p>Welcome to Beautiful Soup</p></body></html>"
# 使用BeautifulSoup解析HTML文档
soup = BeautifulSoup(html_doc, 'html.parser')
# 获取注释内容
comment = soup.body.contents[0]
# 打印注释内容
print(comment) # 输出:' This is a comment '
二、补充
1、获取Tag对象
获取某个指定的tag有两种情况:一种是获取指定的第一个标签(这种实际中用得很少),另一种是获取指定的全部标签对
(1)获取指定的第一个标签
获取指定的第一个标签就是使用前面介绍的"soup对象.标签名"
示例:soup对象.标签名
from bs4 import BeautifulSoup
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html,"lxml")#一个<class 'bs4.BeautifulSoup'>
tag_p = soup.p
print("p标签对为:",tag_p)
tag_a = soup.a
print("a标签对为:",tag_a)
"""
p标签对为: <p class="title" name="dromouse"><b>The Dormouse's story</b></p>
a标签对为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
"""
(2)获取指定的全部标签对
要获取一个文档中某个指定的所有标签,就需要使用find_all()方法:BeautifulSoup对象或Tag对象都可以使用find_all()或find()方法来找其下面的子标签(只是查找范围不一样:BeautifulSoup对象->整个xml对象内,Tag对象->该Tag对象内)
其参数可以是很多类型,最常用的是:传入需要获取的标签的标签名
find_all()方法返回的是一个由所有符合要求的标签组成的列表
个人建议:不管HTML或XML文档中有无重复的标签,都最好用find_all()方法来找对应的Tag对象。
示例:find_all()
from bs4 import BeautifulSoup
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html,"lxml")
tag_body = soup.find_all("p") #获取所有p标签的tag对象
print("p标签对为:",tag_body)
tag_a = soup.find_all("a") #获取所有a标签的tag对象
print("a标签对为:",tag_a)
"""
p标签对为: [<p class="title" name="dromouse"><b>The Dormouse's story</b></p>, <p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>, <p class="story">...</p>]
a标签对为: [<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
"""
ps:
find_all()方法用于返回整个文档中所有符合要求的标签对:返回值是由所有符合要求的tag对象组成的列表(遍历后就是一个个tsg对象)。
同样的方法还有find()方法:只是find()方法只是返回第一个符合要求的标签对。
使用这种方法的话,就可以将标签名定义成变量,方便后续使用。
2、tag对象的name和attrs属性
自己理解的解析过程就是:soup对象->Tag对象->通过tag对象的name、attrs和另外的string属性来获取想要的数据
使用这种方法的话也是:只会返回第一个符合要求的标签名的name和attrs(因为返回的只有一个tag对象)
标签对的attrs属性返回值是一个字典,可以对其使用字典的方法
tag的属性可以被添加,删除或修改,与字典处理方法一致,如:tag['class'] = 'verybold'
# 修改第一个a标签的 class 属性值
soup.a["class"] = ["sister c1"]
# 删除第一个a标签的id属性值
del soup.a["id"]
print(soup)
# 可以发现第一个a标签的id属性值被删除了
完整示例
from bs4 import BeautifulSoup
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1"><!-- Elsie --></a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html,"lxml")
def parse_msg(tagName):
tags = soup.find_all(tagName) #find_all()返回的是一个由tag对象组成的列表,因此需要遍历
for tag in tags:
print("标签的tag对象为为:", tag)
print("标签的名称为:",tag.name)
print("标签的属性为:",tag.attrs)
print("标签的数据为:", tag.string)
parse_msg("a")
parse_msg("p")
"""
标签的tag对象为为: <a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>
标签的名称为: a
标签的属性为: {'class': ['sister'], 'href': 'http://example.com/elsie', 'id': 'link1'}
标签的数据为: Elsie
标签的tag对象为为: <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>
标签的名称为: a
标签的属性为: {'class': ['sister'], 'href': 'http://example.com/lacie', 'id': 'link2'}
标签的数据为: Lacie
标签的tag对象为为: <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>
标签的名称为: a
标签的属性为: {'class': ['sister'], 'href': 'http://example.com/tillie', 'id': 'link3'}
标签的数据为: Tillie
标签的tag对象为为: <p class="story">Once upon a time there were three little sisters; and their names were
<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>,
<a class="sister" href="http://example.com/lacie" id="link2">Lacie</a> and
<a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
标签的名称为: p
标签的属性为: {'class': ['story']}
标签的数据为: None
标签的tag对象为为: <p class="story">...</p>
标签的名称为: p
标签的属性为: {'class': ['story']}
标签的数据为: ...
"""
标签:对象,标签,BeautifulSoup,爬虫,soup,tag,四大,属性 From: https://www.cnblogs.com/xiao01/p/18104295
上面的流程就是:先使用find_all()方法获取所有符合要求的tag对象组成的列表,然后遍历出每一个tag对象,最后获得每一个tag对象的name、attrs属性以及string
也可以使用soup.标签名["属性名"]来获取指定名字的attrs属性
这种嵌套在里面的标签对,如果返回的是外层的tag对象,那也只能获得外层tag对象的name和attrs属性