学习笔记Python爬虫Python 页面解析:Beautiful Soup库的使用
小嗷犬Beautiful Soup库简介
Beautiful Soup 简称 BS4(其中 4 表示版本号)是一个 Python 中常用的页面解析库,它可以从 HTML 或 XML 文档中快速地提取指定的数据。
相比于之前讲过的 lxml
库,Beautiful Soup 更加简单易用,不像正则和 XPath 需要刻意去记住很多特定语法,尽管那样会效率更高更直接。
对大多数 Python 使用者来说,好用会比高效更重要。
Beautiful Soup库为第三方库,需要我们通过pip
命令安装:
BS4 解析页面时需要依赖文档解析器,所以还需要一个文档解析器。
Python 自带了一个文档解析库 html.parser
, 但是其解析速度稍慢,所以我们结合上篇内容(Python 文档解析:lxml库的使用),安装 lxml
作为文档解析库:
Beautiful Soup库方法介绍
使用 bs4 的初始化操作,是用文本创建一个 BeautifulSoup
对象,并指定文档解析器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from bs4 import BeautifulSoup
html_str = ''' <div> <ul> <li class="web" id="0"><a href="www.python.org">Python</a></li> <li class="web" id="1"><a href="www.java.com">Java</a></li> <li class="web" id="2"><a href="www.csdn.net">CSDN</a></li> </ul> </div> '''
soup = BeautifulSoup(html_str, 'lxml')
print(soup.prettify())
|
bs4 提供了find_all()
与find()
两个常用的查找方法它们的用法如下:
find_all()
find_all()
方法用来搜索当前 tag
的所有子节点,并判断这些节点是否符合过滤条件,最后以列表形式将符合条件的内容返回,语法格式如下:
1
| find_all(name, attrs, recursive, text, limit)
|
参数说明:
- name:查找所有名字为 name 的 tag 标签,字符串对象会被自动忽略。
- attrs:按照属性名和属性值搜索 tag 标签,注意由于 class 是 Python 的关键字,所以要使用 “class_”。
- recursive:find_all() 会搜索 tag 的所有子孙节点,设置 recursive=False 可以只搜索 tag 的直接子节点。
- text:用来搜文档中的字符串内容,该参数可以接受字符串 、正则表达式 、列表、True。
- limit:由于 find_all() 会返回所有的搜索结果,这样会影响执行效率,通过 limit 参数可以限制返回结果的数量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| from bs4 import BeautifulSoup
html_str = ''' <div> <ul> <li class="web" id="0"><a href="www.python.org">Python</a></li> <li class="web" id="1"><a href="www.java.com">Java</a></li> <li class="web" id="2"><a href="www.csdn.net">CSDN</a></li> </ul> </div> ''' soup = BeautifulSoup(html_str, 'lxml')
print(soup.find_all("li")) print(soup.find_all("a")) print(soup.find_all(text="Python"))
|
上面程序使用 find_all()
方法,来查找页面中所有的<li></li>
标签、<a></a>
标签和"Python"
字符串内容。
find()
find()
方法与 find_all()
方法极其相似,不同之处在于 find()
仅返回第一个符合条件的结果,因此 find()
方法也没有limit
参数,语法格式如下:
1
| find(name, attrs, recursive, text)
|
除了和 find_all()
相同的使用方式以外,bs4 为 find()
方法提供了一种简写方式:
这两行代码的功能相同,都是返回第一个<li></li>
标签,完整程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from bs4 import BeautifulSoup
html_str = ''' <div> <ul> <li class="web" id="0"><a href="www.python.org">Python</a></li> <li class="web" id="1"><a href="www.java.com">Java</a></li> <li class="web" id="2"><a href="www.csdn.net">CSDN</a></li> </ul> </div> ''' soup = BeautifulSoup(html_str, 'lxml')
print(soup.li) print(soup.a)
|
上面的程序会打印出第一个<li></li>
标签和第一个<a></a>
标签。
select()
bs4 支持大部分的 CSS 选择器,比如常见的标签选择器、类选择器、id 选择器,以及层级选择器。Beautiful Soup 提供了一个 select()
方法,通过向该方法中添加选择器,就可以在 HTML 文档中搜索到与之对应的内容。
应用如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| from bs4 import BeautifulSoup
html_str = ''' <div> <ul> <li class="web" id="web0"><a href="www.python.org">Python</a></li> <li class="web" id="web1"><a href="www.java.com">Java</a></li> <li class="web" id="web2"><a href="www.csdn.net">CSDN</a></li> </ul> </div> ''' soup = BeautifulSoup(html_str, 'lxml')
print(soup.select('body'))
print(soup.select('a[href]'))
print(soup.select('.web'))
print(soup.select('div ul'))
print(soup.select('#web1'))
|
更多方法及其详细使用说明,请参见官方文档:
https://beautiful-soup-4.readthedocs.io/en/latest/
代码实例
学会了 Beautiful Soup ,让我们试着改写一下上次的爬虫代码吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import os import sys import requests from bs4 import BeautifulSoup
x = requests.get('https://www.csdn.net/')
soup = BeautifulSoup(x.text, 'lxml')
img_list = soup.select('img[src]')
os.chdir(os.path.dirname(sys.argv[0]))
if not os.path.exists('img'): os.mkdir('img') print('创建文件夹成功') else: print('文件夹已存在')
for i in range(len(img_list)): item = img_list[i]['src'] img = requests.get(item).content if item.endswith('jpg'): with open(f'./img/{i}.jpg', 'wb') as f: f.write(img) elif item.endswith('jpeg'): with open(f'./img/{i}.jpeg', 'wb') as f: f.write(img) elif item.endswith('png'): with open(f'./img/{i}.png', 'wb') as f: f.write(img) else: print(f'第{i + 1}张图片格式不正确') continue print(f'第{i + 1}张图片下载成功')
|
这就是本文的全部内容了,快去动手试试吧!