Beautiful Soup应用示例
简介
Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库,它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。
快速入门
from bs4 import BeautifulSoup
broken_html = '<ul class=country><li>Area<li>Population</ul>'
soup = BeautifulSoup(broken_html, 'lxml')
fixed_html = soup.prettify()
# <html>
# <body>
# <ul class="country">
# <li>
# Area
# </li>
# <li>
# Population
# </li>
# </ul>
# </body>
# </html>
print(fixed_html)
ul = soup.find('ul', attrs={'class': 'country'})
# <li>Area</li>
ul.find('li')
#[<li>Area</li>, <li>Population</li>]
ul.find_all('li')
安装Beautiful Soup
- Beautiful Soup 4通过PyPi发布,可以通过pip安装。
pip install beautifulsoup4
- 安装解析器,Beautiful Soup支持python标准库中的HTML解析器,还支持一些第三方的解析器,比如lxml和html5lib。
pip install lxml
pip install html5lib
- 解析器对比
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup, "html.parser") | Python的内置标准库,执行速度适中,文档容错能力强 | Python3.2.2前的版本中文档容错能力强 |
lxml HTML解析器 | BeautifulSoup(markup, "lxml") | 速度快,文档容错能力强 | 需要安装C语言库 |
lxml XML解析器 | BeautifulSoup(markup, ["lxml-xml"]) ,BeautifulSoup(markup, "xml") | 速度快,唯一支持XML的解析器 | 需要安装C语言库 |
html5lib | BeautifulSoup(markup, "html5lib") | 最好的容错性,以浏览器的方式解析文档,生成HTML5格式的文档 | 速度慢,不依赖外部扩展 |
- lxml的使用
import lxml.html as lh
broken_html = '<ul class=country><li>Area<li>Population</ul>'
tree = lh.fromstring(broken_html)
fixed_html = lh.tostring(tree, pretty_print=True)
# b'<ul class="country">\n<li>Area</li>\n<li>Population</li>\n</ul>\n'
print(fixed_html)
对象的种类
Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:
Tag
,NavigableString
,BeautifulSoup
,Comment
。
- Tag
(1)Tag对象与XML或HTML原生文档中的tag相同
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
# bs4.element.Tag
type(tag)
(2)Tag有很多方法和属性,最重要的属性name和attributes
# 通过.name获取标签名, 'b'
tag.name
# 如果改变了tag的name,那将影响所有通过当前Beautiful Soup对象生成的HTML文档
tag.name = "blockquote"
# <blockquote class="boldest">Extremely bold</blockquote>
tag
# 一个tag可能有很多个属性,tag有一个class属性,['boldest']
tag['class']
# 也可以直接使用“点”取属性,{'class': ['boldest']}
tag.attrs
# tag的属性可以被添加,删除或修改,tag的属性操作方法与字典一样
tag['class'] = 'verybold'
tag['id'] = 1
# <blockquote class="verybold" id="1">Extremely bold</blockquote>
tag
del tag['class']
del tag['id']
# <blockquote>Extremely bold</blockquote>
tag
# 多值属性,HTML 4定义了一系列可以包含多个值的属性.在HTML5中移除了一些,却增加更多.最常见的多值的属性是class,在bs4中多值属性返回类型是list
css_soup = BeautifulSoup('<p class="body strikeout"></p>')
# ['body', 'strikeout']
css_soup.p['class']
# 将tag转换成字符串时,多值属性会合并为一个值
rel_soup = BeautifulSoup('<p>Back to the <a rel="index">homepage</a></p>')
# ['index']
rel_soup.a['rel']
rel_soup.a['rel'] = ['index', 'contents']
# <p>Back to the <a rel="index contents">homepage</a></p>
print(rel_soup.p)
- 可以遍历的字符串
# 字符串常被包含在tag内,NavigableString类用来包装tag中的字符串
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b
# 'Extremely bold'
tag.string
# bs4.element.NavigableString
type(tag.string)
# tag中包含的字符串不能编辑,但是可以使用replace_with()方法替换
tag.string.replace_with("No longer bold")
# <blockquote>No longer bold</blockquote>
tag
-
BeautifulSoup对象表示的是一个文档的全部内容,大多数时候可以把它当做Tag对象,因为BeautifulSoup对象并不是真正的HTML或XML的tag,所以没有name和attribute属性。
-
Tag,NavigableString,BeautifulSoup几乎覆盖了html和xml中的所有内容,但是还有一些特殊对象入文档的注释部分。Comment对象是一个特殊类型的NavigableString对象。
markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>"
soup = BeautifulSoup(markup)
comment = soup.b.string
'bs4.element.Comment'
type(comment)