文章目录
1安装
为了安装速度,使用国内镜像安装。
在Terminal下输入以下代码:
pip install beautifulsoup4 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
2解析器
与Scrapy相比,bs4在接受数据和进行过滤之间多了一个解析的过程。这时候就需要一个解析器,解析器有很多种,不同的解析器最终要处理的数据也会不同。这里我们使用官方推荐的解析器lxml。
2.1安装lxml
在Terminal下输入以下代码:
pip install lxml
3使用bs4过滤器
Scrapy可以使用XPath
、css
过滤器;bs4使用BeautifulSoup
作为过滤器,也支持嵌套过滤,不过BeautifulSoup
更加方便灵活。可以配合第三方解析器,使bs4威力更加强大。
3.1实例
后续的所有实例都以维基百科首页为例。
3.1.1读取
将维基百科首页另存为html
文件,使用BeautifulSoup
读取:
soup=BeautifulSoup(open('C:/Users/38266/Desktop/test.html'),'lxml')
出现以下错误:
UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xa7 in position 1302: illegal multibyte sequence
3.1.2问题分析
编码问题。将一个字符串,通过gbk
的方式,去解码,想要获得Unicode
字符串,结果出错了
3.1.3解决办法
方法一:
给open
添加参数’rb’
.
soup=BeautifulSoup(open('C:/Users/38266/Desktop/test.html','rb'),'lxml')
可以看到,问题解决。
通过查阅open
文件,'rb’
是参数mode
的值。指以二进制
读取文件。
方法二:
给open
添加参数encoding=‘UTF-8’
.
soup=BeautifulSoup(open('C:/Users/38266/Desktop/test.html',encoding='utf-8'),features='lxml')
解释:确定html是UTF-8
编码,所以直接指定以UTF-8
解码。UTF-8
编码用gbk
去解肯定会出错。
方法三:
给open
添加参数errors='ignore’
soup=BeautifulSoup(open('C:/Users/38266/Desktop/test.html',errors='ignore'),features='lxml')
提高读取字符串的容错性,旨在忽略对于部分字符的读取错误。
问题:有导致中文字符显示不正常的分享。
心得:UTF-8和gbk都是常用的中文编码方式,bs在检测编码时,容易把UTF-8识别成gbk。以后如果还遇到类似问题,均可以考虑从更改解码方式、忽略错误、二进制解码方向思考。
3.1.3输出结果
print(soup.prettify())
将html写入到txt中:
with open(file='C:/Users/38266/Desktop/test.txt',encoding='utf-8',mode='w') as fp:
fp.write(soup.prettify())
至此,说明我们的BeautifulSoup可以正常使用。
4标签定位
4.1位置定位
4.1.1 默认位置
例子,找出第一个div
标签。
soup.find('div')
运行结果
4.1.2通过索引位置查找
**在html中,同名标签不可能只出现一次。**我们通过find_all
方法获得所有同名的标签列表,然后通过列表索引[i]
访问已知位置的特定标签。
获得所有td
标签:
sets= soup.find_all('td')
获得第一个td
标签:
res=soup.find_all('td')[0]
4.1.3 顾及属性的标签查找
在很多时候,我们并不知道感兴趣的=标签在哪个位置,但是很容易看出他具备一个和其他同类标签不同的属性值。
使用attrs
。
获得value=1
的td
标签。
soup.find_all('td',attrs={'value':'4'})
# 运行结果:[<td class="line-number" value="4"></td>]
如果html中还存在标签相同、属性相同的标签,则该函数会返回一个 list
。当然,这个情况非常少见。如果发生,我们则可以通过父标签的不同来区分。具体实例,在后面的学习中强调。
5小结
本文对bs4进行了入门级的介绍,总体来说,bs解析很方便,入门较容易。后续需要通过在不同场景中的练习,总结经验。