文章目录
1-基本介绍
BeautifulSoup 提供一些简单的、Python 式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据。
BeautifulSoup 自动将输入文档转换为 Unicode 编码,输出文档转换为 utf-8 编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时你仅仅需要说明一下原始编码方式就可以了。
简单来说,BeautifulSoup 就是 Python 的一个 HTML 或 XML 的解析库,可以用它来方便地从网页中提取数据。
2-解析器
Beautiful Soup 在解析时实际上依赖解析器,它除了支持 Python 标准库中的 HTML 解析器外,还支持一些第三方解析器(比如 lxml)。
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
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 语言库 |
html5lib | BeautifulSoup(markup, “html5lib”) | 最好的容错性、以浏览器的方式解析文档、生成 HTML5 格式的文档 | 速度慢、不依赖外部扩展 |
通过以上对比可以看出,lxml 解析器有解析 HTML 和 XML 的功能,而且速度快,容错能力强,所以推荐使用它。
如果使用 lxml,那么在初始化 Beautiful Soup 时,可以把第二个参数改为 lxml 即可:
from bs4 import BeautifulSoup
soup = BeautifulSoup('<p>Hello</p>', 'lxml')
print(soup.p.string)
3-原理介绍
1.实例化一个BeautifulSoup对象,并且将页面源码数据加载到该对象中
from bs4 import BeautifulSoup #导包
#1.将本地的html文档中的数据加载到该对象中
fp = open('./test.html','r',encoding='utf-8')
soup = BeautifulSoup(fp,'lxml')
#2.将互联网上获取的页面源码加载到该对象中
page_text = response.txt
soup = BeautifulSoup(page_text,'lxml')
#第二种比较常用
soup.prettify() #把要解析的字符串以标准的缩进格式输出
2.通过调用BeautifulSoup对象中相关的属性或者方法进行标签定位和数据提取
1)节点选择器⭐
常用情况
节点选择器 | ||
---|---|---|
soup.tagName:返回的是文档中第一次出现的tagName的内容 | soup.a 第一个 a标签 |
<a>xxxx</a> |
soup.title 获取第一个title节点 |
结果 <title>The Dormouse’s story </title> |
|
提取节点文本.string | soup.title.string | 结果: The Dormouse’s story 当有多个节点时,这种选择方只会选择到第一个匹配的节点,其他的后面节点都会忽略 |
获取节点的名称.name | soup.title.name | 结果:title |
获取标签的属性值attrs或者attrs[‘xxx’] | soup.p.attrs soup.p.attrs[‘name’] |
结果: {‘class’: [‘title’], ‘name’: ‘dromouse’} dromouse attrs 的返回结果是字典形式,它把选择的节点的所有属性和属性值组合成一个字典。 如果要获取 name 属性,就相当于从字典中获取某个键值,只需要用中括号加属性名就可以 |
获取标签的属性值方法2:直接在节点元素后面加中括号,传入属性名就可以了 | soup.p[‘name’] soup.p[‘class’] |
结果: dromouse [‘title’] name属性的值是唯一的,返回的结果就是单个字符串。 对于class,一个节点元素可能有多个class,所以返回的是列表 |
获取内容.text | soup.a.text #可以获取某一个标签中所有的文本内容 | |
获取内容.string | soup.a.string #值可以获取该标签下面直系的文本内容 | beautifulsoup中.string与.text的区别 .string可以返回当前节点中的内容,但是当前节点包含子节点时,.string不知道要获取哪一个节点中的内容,故返回空 .text(或者.get_text())可以返回当前节点所包含的所有文本内容,包括当前节点的子孙节点 |
获取内容.get_text() | soup.a.get_text() #可以获取某一个标签中所有的文本内容 | |
嵌套选择 | soup.head.title.string |
小案例
html = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title" name="dromouse"><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="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
from bs4 import BeautifulSoup
soup = BeautifulSoup(html,'lxml')
#获取<title></title>的元素
print(soup.title)
"""
<title>The Dormouse's story</title>
"""
#查看类型
#bs4.element.Tag 类型,这是Beautiful Soup中一个重要的数据结构。
#经过选择器选择后,返回结果都是bs4.element.Tag类型,它同样可以继续调用节点进行下一步的选择。
#这样就可以做嵌套选择了!!!
#Tag 具有一些属性,比如 string 属性,调用该属性,可以得到节点的文本内容
print(type(soup.title))