python tag对象下有多个标签、属性_Python BeautifulSoup使用教程|Tag对象,HTML标签,Attributes,,find_all,attrs参数,limit,recur...

本文详细介绍了如何使用Python的BeautifulSoup库解析HTML和XML文档,提取所需数据。从库的安装到Tag对象的使用,包括获取标签、属性、字符串、子节点、父节点和兄弟节点等方法,还涵盖了find_all()和find()函数的使用,以及CSS选择器的选取。通过实例展示了如何从网页中抓取指定标签和属性,是学习BeautifulSoup的实用教程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库,简单来说,它能将HTML的标签文件解析成树形结构,然后方便地获取到指定标签的对应属性。通过Beautiful Soup库,我们可以将指定的class或id值作为参数,来直接获取到对应标签的相关数据。

当前最新的 Beautiful Soup 版本为4.8.1。本文示例使用的Python版本为3.7。

Mac系统,直接通过命令安装库:

sudo easy_install beautifulsoup4

安装完成后,尝试包含库运行:

from bs4 import BeautifulSoup

若没有报错,则说明库已正常安装完成。

windows直接用pycharm安装如下图:

开始

本文会通过这个网页:https://www.pythonf.cn/ 来进行示例讲解,如下图所示

BeautifulSoup 对象初始化

将一段文档传入 BeautifulSoup 的构造方法,就能得到一个文档对象。如下代码所示,文档通过请求url获取:#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

BeautifulSoup 构造方法的第二个参数为文档解析器,若不传入该参数,BeautifulSoup会自行选择最合适的解析器来解析文档,不过会有警告提示。

也可以通过文件句柄来初始化,可先将HTML的源码保存到本地同级目录 reo.html,然后将文件名作为参数:

soup = BeautifulSoup(open('reo.html'))

可以打印 soup,输出内容和HTML文本无二致,此时它为一个复杂的树形结构,每个节点都是Python对象。

Ps. 接下来示例代码中所用到的 soup 都为该soup。

Tag

Tag对象与HTML原生文档中的标签相同,可以直接通过对应名字获取#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

tag = soup.title

print(tag)

打印结果:

Name

通过Tag对象的name属性,可以获取到标签的名称tag = soup.title

print(tag.name)

Attributes

一个tag可能包含很多属性,如id、class等,操作tag属性的方式与字典相同。

例如网页中导航栏标签 nav

获取它 class 属性的值#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

tag = soup.nav

c = tag['class']

print(c)

也可以直接通过 .attrs 获取所有的属性#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

tag = soup.nav

attrs = tag.attrs

print(attrs)

ps. 因为class属于多值属性,所以它的值为数组。

tag中的字符串

通过 string 方法获取标签中包含的字符串#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

tag = soup.title

s = tag.string

print(s)

子节点

通过Tag的 name 可以获取到对应标签,多次调用这个方法,可以获取到子节点中对应的标签。

如下图:

我们希望获取到 nav 标签中的 li#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

tag = soup.nav.li

print(tag)

打印结果:

通过 . 属性只能获取到第一个tag,若想获取到所有的 li 标签,可以通过 find_all() 方法#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

tag = soup.nav.find_all('li')

print(tag)

获取到的是包含所有li标签的列表。

tag的 .contents 属性可以将tag的子节点以列表的方式输出:#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

tag = soup.nav.ul

contents = tag.contents

print(contents)

打印 contents 可以看到列表中不仅包含了 li 标签内容,还包括了换行符 '\n'

tag的 .children 生成器,可以对tag的子节点进行循环#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

tag = soup.nav.ul

children = tag.children

print(children)

forchild inchildren:

print(child)

父节点

通过 .parent 属性来获取某个元素的父节点,nav的 父节点为 body。#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

tag = soup.nav

print(tag.parent.name)

或者通过 .parents 属性遍历所有的父辈节点。#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

tag = soup.nav

forp intag.parents:

print(p.name)

兄弟节点

.next_sibling 和 .previous_sibling 属性用来插叙兄弟节点,使用方式与其他的节点类似。

find_all()

find_all(name , attrs , recursive , string , ** kwargs)

name 参数

查找所有名字为 name 的tag#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

print(soup.find_all('title'))

print(soup.find_all('li'))

keyword 参数

如果指定参数的名字不是内置的参数名(name , attrs , recursive , string),则将该参数当成tag的属性进行搜索,不指定tag的话则默认为对所有tag进行搜索。

如,搜索所有 id 值为 footer 的标签#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

print(soup.find_all(id='key'))

加上标签的参数

soup.find_all('input', id='key')

获取所有 class 为 collapse navbar-collapse的div#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

print(soup.find_all('div', class_='collapse navbar-collapse'))

这里需要注意一点,因为 class 为Python的保留关键字,所以作为参数时加上了下划线,为“class_”。

指定名字的属性参数值可以包括:字符串、正则表达式、列表、True/False。

True/False

是否存在指定的属性。

搜索所有带有 action属性的标签#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

print(soup.find_all(action=True))

搜索所有不带 action属性的标签(仔细观察会发现,搜索结果还是会有带 action的标签,那是不带 action标签的子标签,这里需要注意一下。)

soup.find_all(action=False)

可以指定多个参数作为过滤条件:

搜索 src 属性中包含 python字符串,并且 class 为 lazy 的标签:

soup.find_all(src=re.compile("python"), class_='lazy')

有些属性不能作为参数使用,如 data-**** 属性。在上面的例子中,data-original 不能作为参数使用,运行起来会报错,SyntaxError: keyword can't be an expression*。

attrs 参数

定义一个字典参数来搜索对应属性的tag,一定程度上能解决上面提到的不能将某些属性作为参数的问题。

例如,搜索包含 data-original 属性的标签

print soup.find_all(attrs={'data-original': True})

搜索 data-original 属性中包含pythonf字符串的标签

soup.find_all(attrs={'data-original': re.compile("pythonf")})

搜索 data-original 属性为指定值的标签

soup.find_all(attrs={'data-original': 'www.pythonf.cn'})

string 参数

和 name 参数类似,针对文档中的字符串内容。

搜索包含 ‘教程’字符串的标签:#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

importre

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

print(soup.find_all(string=re.compile("教程")))

结果见下图所示:

limit 参数

find_all() 返回的是整个文档的搜索结果,如果文档内容较多则搜索过程耗时过长,加上 limit 限制,当结果到达 limit 值时停止搜索并返回结果。

搜索 class 为 row 的 div 标签,只搜索3个

soup.find_all('div', class_='row', limit=3)

打印结果为一个包含3个元素的列表,实际满足结果的标签在文档里不止3个。

recursive 参数

find_all() 会检索当前tag的所有子孙节点,如果只想搜索tag的直接子节点,可以使用参数 recursive=False。

find()

find(name , attrs , recursive , string , ** kwargs)

find() 方法和 find_all() 方法的参数使用基本一致,只是 find() 的搜索方法只会返回第一个满足要求的结果,等价于 find_all() 方法并将limit设置为1。

soup.find('div', class_='row')

搜索结果一致,唯一的区别是 find_all() 返回的是一个数组,find() 返回的是一个元素。

当没有搜索到满足条件的标签时,find() 返回 None, 而 find_all() 返回一个空的列表。

CSS选择器

Tag 或 BeautifulSoup 对象通过 select() 方法中传入字符串参数, 即可使用CSS选择器的语法找到tag。

语义和CSS一致,搜索 nav标签下的 ul 标签中的 li 标签#coding:utf-8frombs4 importBeautifulSoup

fromurllib importrequest

importre

url = 'https://pythonf.cn'headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}

req = request.Request(url, headers=headers)

response = request.urlopen(req)

content = response.read()

soup = BeautifulSoup(content, 'html.parser')

print(soup.select('nav ul li'))

通过类名查找,两行代码的结果一致,搜索 class 为 thumb 的标签

soup.select('.row')

soup.select('[class~=row]')

通过id查找,搜索 id 为 sponsor 的标签

soup.select('#key')

通过是否存在某个属性来查找,搜索具有 id 属性的 li 标签

soup.select('li[id]')

通过属性的值来查找查找,搜索 id 为 sponsor 的 li 标签

soup.select('li[id="key"]')

其他

其他的搜索方法还有:

find_parents() 和 find_parent()

find_next_siblings() 和 find_next_sibling()

find_previous_siblings() 和 find_previous_sibling()

参数的作用和 find_all()、find() 差别不大,这里就不再列举使用方式了。这两个方法基本已经能满足绝大部分的查询需求。

还有一些方法涉及文档树的修改。对于爬虫来说大部分工作只是检索页面的信息,很少需要对页面源码做改动,所以这部分的内容也不再列举。

具体详细信息可直接参考Beautiful Soup库的官方说明文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值