和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据,lxml 只会局部遍历,而Beautiful Soup 是基于HTML DOM的,会载入整个文档,解析整个DOM树,因此时间和内存开销都会大很多,所以性能要低于lxml。BeautifulSoup 用来解析 HTML 比较简单,API非常人性化,支持CSS选择器、Python标准库中的HTML解析器,也支持 lxml 的 XML解析器,更多详情请看BeautifulSoup4官方文档。
更新前几篇文章,我们简单来对比一下这个Python包:
抓取工具 | 速度 | 使用难度 | 安装难度 |
---|---|---|---|
正则 | 最快 | 困难 | 无(内置) |
BeautifulSoup | 慢 | 最简单 | 简单 |
lxml | 快 | 简单 | 一般 |
1. 实例一
# 创建 Beautiful Soup 对象
soup = BeautifulSoup(html,'lxml') # lxml解析器
# 打开本地 HTML 文件的方式来创建对象
#soup = BeautifulSoup(open('index.html'))
# 格式化输出 soup 对象的内容
print soup.prettify()
2. 实例二
Tag 标签
# 创建 Beautiful Soup 对象
soup = BeautifulSoup(html)
print soup.title
# <title>The Dormouse's story</title>
print soup.head
# <head><title>The Dormouse's story</title></head>
print type(soup.p)
# <class 'bs4.element.Tag'>
print soup.name
# [document] #soup 对象本身比较特殊,它的 name 即为 [document]
print soup.head.name
# head #对于其他内部标签,输出的值便为标签本身的名称
print soup.p.attrs
# {'class': ['title'], 'name': 'dromouse'}
# 在这里,我们把 p 标签的所有属性打印输出了出来,得到的类型是一个字典。
soup.p['class'] = "newClass"
print soup.p # 可以对这些属性和内容等等进行修改
# <p class="newClass" name="dromouse"><b>The Dormouse's story</b></p>
del soup.p['class'] # 还可以对这个属性进行删除
print soup.p
# <p name="dromouse"><b>The Dormouse's story</b></p>
3. 实例三
直接子节点
.content
tag 的 .content 属性可以将tag的子节点以列表的方式输出
print soup.head.contents
#[<title>The Dormouse's story</title>]
输出方式为列表,我们可以用列表索引来获取它的某一个元素
print soup.head.contents[0]
#<title>The Dormouse's story</title>
直接子节点
.children
它返回的不是一个 list,不过我们可以通过遍历获取所有子节点。
我们打印输出 .children 看一下,可以发现它是一个 list 生成器对象
print soup.head.children
#<listiterator object at 0x7f71457f5710>
for child in soup.body.children:
print child
输入的是每个标签对象
4. 实例四
这就是另一种与 find_all 方法有异曲同工之妙的查找方法,就是CSS选择器。
- 写 CSS 时,标签名不加任何修饰,类名前加.,id名前加#
- 在这里我们也可以利用类似的方法来筛选元素,用到的方法是 soup.select(),返回类型是 list
通过标签名查找
print soup.select('title')
#[<title>The Dormouse's story</title>]
通过类名查找
print soup.select('.sister')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>, <a class="sister" href="http://example.com/lacie" id="link2">Lacie</a>, <a class="sister" href="http://example.com/tillie" id="link3">Tillie</a>]
通过 id 名查找
print soup.select('#link1')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]
组合查找
print soup.select('p #link1')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]
直接子标签查找,则使用 > 分隔
print soup.select("head > title")
#[<title>The Dormouse's story</title>]
属性查找
print soup.select('a[href="http://example.com/elsie"]')
#[<a class="sister" href="http://example.com/elsie" id="link1"><!-- Elsie --></a>]
获取内容
以上的 select 、find、find_all方法返回的结果都是列表形式,可以遍历形式输出,然后用 get_text()、string方法来获取它的内容。
soup = BeautifulSoup(html, 'lxml')
print soup.select('title')[0].get_text()
for title in soup.select('title'):
print title.get_text()
print title.string
5. 实例五
获取标签属性值
from bs4 import BeautifulSoup
import os
html = '<input class="nihao" name="haha" value="123">你好,我的朋友</input>'
soup = BeautifulSoup(html,"lxml")
1. 第一种
print soup.find_all('input',attrs={"class":"nihao"})[0].get("class")
2. 第二种
print soup.find('input',attrs={"class":"nihao"}).attrs["value"]
3. 第三种
print soup.find('input',attrs={"class":"nihao"})["value"]
获取标签对象
from bs4 import BeautifulSoup
import os
html = '<input class="nihao" name="haha" value="123">你好,我的朋友</input>'
soup = BeautifulSoup(html,"lxml")
1. 第一种
print soup.find_all('input',attrs={"class":"nihao"})[0]
2. 第二种
print soup.find('input',attrs={"class":"nihao"})
3. 第三种
print soup.select('.nihao')[0]
获取标签内容
from bs4 import BeautifulSoup
import os
html = '<input class="nihao" name="haha" value="123">你好,我的朋友</input>'
soup = BeautifulSoup(html,"lxml")
1. 第一种
input = soup.find_all('input',attrs={"class":"nihao"})[0]
print input.string
2. 第二种
input = soup.find('input',attrs={"class":"nihao"})
print input.get_text()
注意:BeautifulSoup4最重要的就是实例五,如果把实例五,掌握好用BeautifulSoup4爬取数据就没有问题了。
网友评论