前言:
帮助文档地址:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/
BeautifulSoup 是第三方库,灵活又方便的网页解析库,处理高效,支持多种解析器,需要安装:pip install BeautifulSoup4;使用时还需要对应的解析器,如果没有必须安装。
导模块:from bs4 import BeautifulSoup
一、解析库
解析器使用方法优势劣势Python标准库BeautifulSoup(markup,‘html.parser’)Python的内置标准库、执行速度适中 、文档容错能力强Python 2.7.3 or 3.2.2)前的版本中文容错能力差lxml HTML 解析器BeautifulSoup(markup,’lxml’)速度快、文档容错能力强需要安装C语言库lxml XML 解析器BeautifulSoup(markup, ‘xml’)速度快、唯一支持XML的解析器需要安装C语言库html5libBeautifulSoup(markup,‘html5lib’)最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档速度慢、不依赖外部扩展二、基本使用:带自动补全html标签
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dormouse"><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="link2">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html, 'lxml')
print(soup.prettify()) # 以标准的缩进格式
print(soup.title.string) # title标签下的内容输出
print(soup.p)# 返回匹配到的第一个
print(type(soup.p))#<class 'bs4.element.Tag'>
print(soup.body.string)#None
三、获取标签
# 获取匹配到标签的名字
print(soup.p.name)
# 获取匹配到标签的属性和属性值,以字典形式返回
print(soup.p.attrs)
# 获取匹配到标签的属性值,两种方法
print(soup.p.attrs['class'])
print(soup.p['class'])
#bs4中 . 和lxml中的 // 含义类似
print(soup.html.head.title)
print(soup.html.title)
print(soup.head.title)
print(soup.title)
四、获取内容和嵌套获取
print(soup.title.string) # title标签下的内容输出
print(soup.head.title.string) # 嵌套获取
五、子节点和子孙结点
# 格式化输出body结点
print(soup.body.prettify())
# 输出body的直接子节点(字符串列表)
print(soup.body.contents)
# 输出body的直接子节点(生成器类型)
result = soup.body.children
for num,child in enumerate(result):
print(num,child)
# 输出body的子孙节点(生成器类型)
result = soup.body.descendants
for num,child in enumerate(result):
print(num,child)
六、父节点和祖父结点
# 父节点
print(soup.a.parent.prettify())
# 祖先结点,列表形式输出,生成器对象序要迭代后才能使用
print(list(enumerate(soup.a.parents)))
七、兄弟结点
# 文本也是结点
# 获取前一个兄弟结点
print(soup.a.previous_sibling)
# 获取下一个的兄弟结点
print(soup.a.next_sibling)
#前一个结点生成器
print(list(enumerate(soup.a.previous_siblings)))
# 后一个结点生成器
print(list(enumerate(soup.a.next_siblings)))
八、标准选择器
8.1 find_all(name,attrs,recursive,text,**kwargs):可根据标签名、属性、内容查找文档
1、name
# 获取标签是ul,以列表输出
print(soup.find_all(name='ul'))
# 获取标签是ul,列表中第0个元素
print(soup.find_all(name='ul')[0])
# 获取标签是ul,下的li标签里的内容
print(soup.find_all(name='ul')[0].li.string)
2、attrs
print(soup.find_all(attrs={'属性名':'属性值'}))
3、text
print(soup.find_all(text=正则表达式)) : 查找所有标签匹配文本信息,包含正则结果,将文本提取
4、print(soup.find()) # 用法与find_all一致,匹配第一个元素输出
8.2 find_parents() find_parent()
find_parents()返回所有祖先节点,find_parent()返回直接父节点。
8.3 find_next_siblings() find_next_sibling()
find_next_siblings()返回后面所有兄弟节点,find_next_sibling()返回后面第一个兄弟节点。
8.4 find_previous_siblings() find_previous_sibling()
find_previous_siblings()返回前面所有兄弟节点,find_previous_sibling()返回前面第一个兄弟节点。
8.5 find_all_next() find_next()
find_all_next()返回节点后所有符合条件的节点, find_next()返回第一个符合条件的节点
8.6 find_all_previous() 和 find_previous()
find_all_previous()返回节点后所有符合条件的节点, find_previous()返回第一个符合条件的节点
九、css选择器
语法:soup.select('css选择器')
# css选择器soup.select('css选择器')返回列表
1、通过标签名查找
print(soup.select('title')) print(soup.select('a')) print(soup.select('b'))
2、通过类名查找
print(soup.select('.sister'))
3、通过 id 名查找
print(soup.select('#link1'))
4、组合查找
组合查找即和写 class文件时,标签名与类名、id名进行的组合原理是一样的,例如查找
p 标签中,id 等于 link1的内容,二者需要用空格分开
print(soup.select('p #link1')) 直接子标签查找,则使用 > 分隔
print(soup.select("head > title"))
5、属性查找
查找时还可以加入属性元素,属性需要用中括号括起来,注意属性和标签属于同一节点,所以中间不能加空格,否则会无法匹配到。
print(soup.select('a[class="sister"]'))
print(soup.select('a[href="http://example.com/elsie"]'))
同样,属性仍然可以与上述查找方式组合,不在同一节点的空格隔开,同一节点的不加空格
print(soup.select('p a[href="http://example.com/elsie"]'))
6、获取内容
可以遍历 select 方法返回的结果,然后用 get_text() 方法来获取它的内容。
soup = BeautifulSoup(html, 'lxml')
print(type(soup.select('title')))
print(soup.select('title')[0].get_text())
for title in soup.select('title'):
print(title.get_text())