BeautifulSoup
灵活方便的网页解析库,处理高效,支持多种解析器。
安装
pip3 install beautifulsoup4
解析库
解析器 | 使用方法 | 注 |
---|---|---|
Python标准库 | BeautifulSoup(markup, “html.parser”) | Python内标准库 |
lxml HTML解析器 | BeautifulSoup(markup, “lxml”) | 速度快、文档容错能力强 |
lxml XML解析器 | BeautifulSoup(markup, “xml”) | 速度快、唯一支持XML的解析器 |
html5lib | BeautifulSoup(markup, “html5lib”) | 最好的容错性、速度慢 |
基本使用
from bs4 import BeautifulSoup # 导入库
html = """
<!DOCTYPE html>
<html lang="zh-CN">
<head><title>用户脚本</title>
<body>
<p class='story'>
hello world
<a htef="http://jjjsls">hssf
<span>safa</span></a>
<a htef="http://dfa3efag">afdhkhe</a>
<a htef="http://agegaef">ttgwrrgdf</a>
</p>
<script src="e718bcef874b8d3b75c29103.js"></script>
<script src="retygfe769878.js"></script>
<meta name="csrf-token"
"""
soup = BeautifulSoup(html, 'lxml') # 用lxml对html进行解析
print(soup.prettify()) # 自动格式化html代码,可以自动补全缺失的代码
print(soup.title.string) # 选择title的内容
标签选择器
# 选择元素
print(soup.title)
print(soup.head)
print(soup.script)
# 获取属性
print(soup.script.attrs['src']) # 也可以不用attrs
print(soup.script['src'])
# 获取内容
print(soup.title.string) # 通过 .string
# 嵌套选择
print(soup.head.title.string) # 先选择head,通过head再选择其中的title, 每一层的类型都是<class 'bs4.element.Tag'>
# 子节点和子孙节点
print(soup.p.contents) # 把所有的子节点以一个列表的形式反回回来
# 和上面相同的也是列出所有子节点,但是这是一个迭代器,需要用循环的方式输出出来
print(type(soup.p.children))
for i, child in enumerate(soup.p.children): # 反回节点内容和其索引
print(i, child)
# 获取其所有的子孙节点,反回的对象也是迭代器
for i, child in enumerate(soup.p.descendants):
print(i, child)
# 父节点和祖先节点
print(soup.a.parent) # 获取父节点
print(list(enumerate(soup.span.parents))) # 获取其祖先节点
# 兄弟节点
print(list(enumerate(soup.a.next_siblings))) # 获取下一个兄弟节点
print(list(enumerate(soup.a.previous_siblings))) # 获取上一个兄弟节点
标准选择器
find_all(name, attrs, recursive, text, **kwargs) 可以根据标签名、属性、内容查找文档
from bs4 import BeautifulSoup
html = """
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>
"""
soup = BeautifulSoup(html, 'lxml')
# name
print(soup.find_all('ul')) # 把ul标签都提取出来,反回一个列表
print(type(soup.find_all('ul')[0])) # 每个元素的类型为<class 'bs4.element.Tag'>
# 这个类型就可以进行层层迭代的查找
for ul in soup.find_all('ul'):
print(ul.find_all('li'))
# attrs
print(soup.find_all(attrs={'id': "list-1"})) # 传入一个字典类的数据进行查找
print(soup.find_all(attrs={'name': 'elements'})) # 找不到反回一个空列表
print(soup.find_all(id="list-1")) # 对于一些特殊的属性可以这样简写
print(soup.find_all(class_="element")) # class在python中也是一个关键字,所以在后面加了一个_
# text
print(soup.find_all(text='Foo')) # 根据text查找,直接会打印出text内容,不会反回整个标签
find(name, attrs, recursive, text, **kwargs) find返回单个元素,find_all返回所有元素
find_parents() find_parent() find_partents()返回所有祖先节点,find_parent()返回直接父节点
find_next_siblings() find_next_sibling() 返回后面所有兄弟节点,返回后面第一个兄弟节点
find_previous_siblings() find_previous_sibling() 返回前面所有兄弟节点, 返回前面第一个兄弟节点
find_all_next() find_next() 返回节点后所有符合条件的节点,返回第一个符合条件的节点
find_all_previous() find_previous() 返回节点后所有符合条件的节点,返回第一个符合条件的节点
CSS选择器
通过select()直接传入CSS选择器即可完成选择
from bs4 import BeautifulSoup
html = """
<div class="panel">
<div class="panel-heading">
<h4>Hello</h4>
</div>
<div class="panel-body">
<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>
<ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>
</div>
</div>"""
soup = BeautifulSoup(html, 'lxml')
print(soup.select('.panel .panel-heading')) # 如果选择class需要加一个 "."
print(soup.select('ul li')) # 选择标签
print(soup.select('#list-2 .element')) # 选择id可以用 "#"
print(type(soup.select('ul')[0])) # <class 'bs4.element.Tag'>
# 获取属性
for ul in soup.select('ul'):
print(ul['id'])
print(ul.attrs['id'])
# 获取内容
for li in soup.select('li'):
print(li.get_text())