文章目录
使用Beautiful Soup解析库
简介
支持的解析器
基本用法
html ="""
<html id="html" manifest="offlintab.appcache">
<meta charset="utf-8">
<title>新标签页</title>
<base>
<link type="text/css" rel="stylesheet" href="/static/css/offlintab-468.css">
<script type="application/javascript" src="/static/js/offlintab-468.js"></script>
<body id="body">
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.prettify()) #把要解析的字符串以标准的缩进格式输出
print(soup.title.string) #输出HTML中title节点的文本内容
#soup.title可以选出HTML中的title节点,再调用string属性就可以得到里面的文本
节点选择器
说明:直接调用节点的名称就可以选择节点元素,再调用string属性就可以得到节点内的文本了,这种选择方式速度非常快。如果单个节点结构层次非常清晰,可以选用这种方式来解析。
提取信息
说明:包括选择元素、获取内容、获取名称、获取属性简单用法
代码说明:
html ="""
<a id="export-to" download="exported.json" hidden="true">
<title>新标签页</title>
<a id="setdefault" hidden="true">设为默认浏览器</a>
<p id="promo" hidden="true">
<button title="关闭"></button>
</a>
<nav id="navpane">
<a id="fx-accounts" hidden="true"></a>
<a data-pane="nav" title="切换至导航页">Nav</a>
<a data-pane="blank" title="切换至空白页">Blank</a>
</nav>
<footer id="footer">
<a href="" title="火狐主页">
<img src="/static/img/Logo-quantum.png" alt="Firefox" />
</a>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print()
print(soup.title) #选择元素
print(soup.title.string) #获取节点内的文本
print(soup.title.name) #获取节点名称
print(soup.p.attrs) #每个节点可能有多个属性,调用attrs获取所有属性
或者 直接使用soup.p['id']
运行结果:
============================= RESTART: F:/bs.py =============================
<html id="html" manifest="offlintab.appcache">
<head>
<meta charset="utf-8"/>
<title>
新标签页
</title>
<base/>
<link href="/static/css/offlintab-468.css" rel="stylesheet" type="text/css"/>
<script src="/static/js/offlintab-468.js" type="application/javascript">
</script>
</head>
<body id="body">
</body>
</html>
新标签页
<title>新标签页</title>
新标签页
title
{'id': 'promo', 'hidden': 'true'}
嵌套选择
说明:上面每一个例子的返回结果都是bs4.element.Tag类型,它同样可以继续调用节点进行操作。
代码说明:
#嵌套选择
html ="""
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<link rel="canonical" href="https://blog.csdn.net/hefenglian/article/details/83450938"/>
<title>Redis数据库介绍(1) - 洞玄之境的博客 - CSDN博客</title>
<link rel="stylesheet" href="https://csdnimg.cn/css/b9b02f.min.css">
</style>
</head>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print()
print(type(soup.head))
print(soup.head.title)
print(soup.head.title.string) #获取节点内的文本
运行结果
============================= RESTART: F:/bs.py =============================
<class 'bs4.element.Tag'>
<title>Redis数据库介绍(1) - 洞玄之境的博客 - CSDN博客</title>
Redis数据库介绍(1) - 洞玄之境的博客 - CSDN博客
关联选择
说明:在做选择的时候,有时候不能做到一步就选到想要的节点元素,需要先选中某一个节点元素,然后以它为基准再选择它的子节点,父节点,兄弟节点等,以下介绍如何选择这些节点元素。
子节点和子孙节点
说明:要得到所有的子节点,可以调用contents属性 或者 调用children属性;
要得到所有的子孙节点的话,可以调用descendants属性。
代码说明:
#关联选择
html ="""
<a id="export-to" download="exported.json" hidden="true">
<title>新标签页</title>
<a id="setdefault" hidden="true">设为默认浏览器</a>
<p id="promo" hidden="true">
<button title="关闭"></button>
</a>
<nav id="navpane">
<a id="fx-accounts" hidden="true"></a>
<a data-pane="nav" title="切换至导航页">Nav</a>
<a data-pane="blank" title="切换至空白页">Blank</a>
<span>Elise</span>
</nav></p>
<footer id="footer">
<a href="" title="火狐主页">
<img src="/static/img/Logo-quantum.png" alt="Firefox" />
</a>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print()
print(soup.p.contents) #返回一个列表
print()
print(soup.p.children) #返回结果是生成器类型,要用for循环输出
for i,child in enumerate(soup.p.children):
print(i,child)
for i,child in enumerate(soup.p.descendants): #返回结果是生成器类型
print(i,child)
#这两行可以写成print(list(enumerate(soup.p.descendants)))直接变为list
父节点和祖先节点
说明:
如果要获取某个节点元素的父节点,可以调用parent属性;
如果要获取某个节点元素的祖先节点,可以调用parents属性。
兄弟节点
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print('Next Sibling',soup.a.next_sibling) #节点的下一个元素
print('Prev Sibling',soup.a.previous_sibling)
print('Next Sibling',list(enumerate(soup.a.next_sibling)))
#返回所有后面节点的生成器,然后用list转一下
print('Prev Sibling',list(enumerate(soup.a.previous_sibling)))
小结
关联元素里面的都可以用提取信息说的方法。
查询方法
说明:前面所讲的选择方法都是通过属性来选择的,这种方法非常快,但是如果进行比较复杂的选择的话,它就比较繁琐,不够灵活了。幸好,Beautiful Soup 还为我们提供了一些查询方法,比如find_all()、find()等,调用他们,然后传入相应的参数就可灵活运用了。
find_all()
说明:find_all, 顾名思义,就是查询所有符合条件的元素。给它传入一些属性或文本,就可以得到符合条件的元素,它的功能十分强大。
它的API如下:find_all(name, attrs, recursive, text, **kwargs)
代码说明下name, attrs,text:
import re
from bs4 import BeautifulSoup
#调用lxml解析器
soup = BeautifulSoup(html,"lxml")
print(soup.find_all(name='a')) #根据节点名来查询元素,返回结果是列表类型,每个元素依然是bs4.element.Tag类型。
print()
print(soup.find_all(attrs={'id': 'export-to'})) #传入一些属性来查询 或者 使用另一个方式print(soup.find_all(id='export-to'))
print()
print(soup.find_all(text = re.compile('a'))) #text参数用来匹配节点的文本,传入的形式可以是字符串,可以是正则表达式对象
find()
说明:除了find_all()方法,还有find()方法,只不过后者返回的是单个元素,也就是第一个匹配的元素,而前者返回的是所有匹配的元素组成的列表。
CSS选择器
CSS选择器参考手册
使用CSS选择器时,只需要调用select()方法,传入相应的CSS选择器即可,如
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
print(soup.select('a p')) # 选择 <a> 元素内部的所有 <p> 元素