bs4,全称BeautifulSoup 4
, 它是Python独有的一种解析方式。也就是说只有Python语言才能够经过这种方式去解析数据。css
BeautifulSoup 3 只支持Python2,因此已经被淘汰了。
官网的介绍是这样的html
Beautiful Soup 提供一些简单的、python 式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,经过解析文档为用户提供须要抓取的数据,由于简单,因此不须要多少代码就能够写出一个完整的应用程序。 Beautiful Soup 自动将输入文档转换为 Unicode 编码,输出文档转换为 utf-8 编码。你不须要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup 就不能自动识别编码方式了。而后,你仅仅须要说明一下原始编码方式就能够了。 Beautiful Soup 已成为和 lxml、html6lib 同样出色的 python 解释器,为用户灵活地提供不一样的解析策略或强劲的速度。
看起来很复杂,我用本身的理解,通俗的解释一下python
咱们知道一个网页的源代码,是由多个标签组成,好比<html>、<div>、<td>、<span>等等组成的,而bs4就是用来帮咱们精肯定位标签位置,从而获取标签或者标签属性中内容的工具。bs4默认自带的解析器,可是官方推荐的是更强大 速度更快的 lxml解析器网络
其余解析器的优缺点
pip install bs4 pip install lxml
使用bs4解析时,推荐使用lxml解析器。这个在用xpath解析的时候也会用到函数
from bs4 import BeautifulSoup
网页源代码,又分为本地已经持久化的HTML文件和网络上直接获取的源代码。工具
若是是本地已经持久化的文件,能够经过下面的方式将源代码加载到bs4对象中测试
fp = open('xxx.html', 'r', encoding='utf-8') # lxml:解析器 soup = BeautifulSoup(fp, 'lxml')
若是是经过requests库获取的网页源代码,经过下面的方式进行加载网站
response = requests.get(url) html = response.text soup = BeautifulSoup(html, 'lxml')
c.数据解析的方法和属性this
bs4可以将复杂的HTML转换成一个树形结构,每一个节点都是Python对象。编码
soup.tagName(标签名): 返回的是文档中第一次出现tagName对应的标签及其相应内容
soup.tageName1.tageName2:返回tag1中tage2的标签及其内容
soup.find:等同于soup.tagName,返回第一个匹配到的对象
soup.find_all:返回全部的匹配到的对象。
经过查看源码会发现,find的本质其实就是调用了find_all, 而后返回第一个元素
参数解释:
def find(self, name=None, attrs={}, recursive=True, text=None, **kwargs): """Return only the first child of this Tag matching the given criteria.""" r = None l = self.find_all(name, attrs, recursive, text, 1, **kwargs) if l: r = l[0] return r
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iXUox6yw-1611066850753)(C:UsersAdministratorAppDataRoamingTyporatypora-user-imagesimage-20210103164834540.png)]
上图是我从某网站截取的部分画面,翻译成HTML以下(只保留了对本次分析有用的部分,为了方便阅读删除了地址的域名信息)
<html> <head><titel>测试Title</titel></head> <body> <div class="test"> <ul> <li> <a href="zhaosi.html"><p>尼古拉斯赵四</p></a> </li> </ul> </div> <div class="nr_zt w1180"> <ul> <li> <a id="star" href="zhengshuang.html"><p>郑爽</p></a> </li> <li> <a id="star" href="zhuyilong.html"><p>朱一龙</p></a> </li> <li> <a id="star" href="zhoudongyu.html"><p>周冬雨</p></a> </li> <li> <a id="star" href="huyitian_1.html"><p>胡一天</p></a> </li> <li> <a id="star" href="yiyangqianxi.html"><p>易烊千玺</p></a> </li> <li> <a id="star" href="dilireba.html"><p>迪丽热巴</p></a> </li> </ul> </div> </body> </html>
看下面几个例子
# 获取第一个li标签 # <li> <a href="http://www.win4000.com/mt/zhengshuang.html"><p>郑爽</p></a> </li> print(soup.li) # # 获取第一个li标签中a标签 # <a href="http://www.win4000.com/mt/zhengshuang.html"><p>郑爽</p></a> print(soup.li.a) #获取第一个li标签中a标签 print(soup.find('li').a) # 获取全部li标签 print(soup.find_all('li')) # 获取title标签 print(soup.title) # 获取a标签的父级标签 print(soup.a.parent) # 获取a标签的父级标签的名字 print(soup.a.parent.name)
如何获取HTML中的href?
分析:href是a标签中的一个属性,而a标签又在li标签中
在bs4中提取标签中的属性能够经过attrs来获取
from bs4 import BeautifulSoup fp = open('baidu.html', 'r', encoding='utf-8') soup = BeautifulSoup(fp, 'lxml') # 若是获取一个能够这样写 result = soup.a.attrs['href'] # zhaosi.html print(result) # 获取所有,可经过先获取a标签 而后遍历获取 all_result = soup.find_all('a') for i in all_result: print(i.attrs['href']) print("* " * 40) # 若是我只想获取id = star的href,须要先对id进行筛选 # 返回全部包含id=star的a标签 star_result = soup.find_all('a', id='star') for i in star_result: print(i.attrs['href']) # 返回包含id的标签(只要有id属性,而且有值的标签都返回) soup.find_all(id=True) # 假设尼古拉斯赵四 不是第一个a标签中的内容.提取对应的href # 须要先定位class=‘test’对应div的位置 # 方法一: result = soup.find('div', 'test') print(result.a['href']) # 方法二(class为python中关键字,所以查找html中的class属性须要添加个下划线 class_) result1 = soup.find('div', class_='test') print(result1.a['href']) # 方法三 result2 = soup.find('div', attrs={'class': 'test'}) # 获取第一个a标签中的文本内容 print(soup.a.text) a_result = soup.find_all('a') for i in a_result: # 生成的是一个迭代器 print(i.strings) print(list(i.strings)) print(i.string) print(i.text)
其余补充
# 返回子孙节点 # children返回迭代器 result = soup.a.children for i in result: print(i) # 返回子孙节点, contents返回列表 r = soup.a.contents print(r) # 能够经过正则对某个属性进行匹配 # 好比返回href中以zh开头的标签 import re reg = re.compile('^zh') result = soup.find_all(href=reg) print(result)
bs4很是强大,还支持css选择器。经过select来完成
<html> <head><titel>测试Title</titel></head> <body> <div class="test"> <ul> <li> <a href="zhaosi.html"><p>尼古拉斯赵四</p></a> </li> </ul> </div> <div class="nr_zt w1180"> <ul> <li> <a id="star" href="zhengshuang.html"><p>郑爽</p></a> </li> <li> <a id="star" href="zhuyilong.html"><p>朱一龙</p></a> </li> <li> <a id="star" href="zhoudongyu.html"><p>周冬雨</p></a> </li> <li> <a id="star" href="huyitian_1.html"><p>胡一天</p></a> </li> <li> <a id="star" href="yiyangqianxi.html"><p>易烊千玺</p></a> </li> <li> <a id="star" href="dilireba.html"><p>迪丽热巴</p></a> </li> </ul> </div> </body> </html>
from bs4 import BeautifulSoup fp = open('baidu.html', 'r', encoding='utf-8') soup = BeautifulSoup(fp, 'lxml') # 返回一个全部a标签的列表 result = soup.select('a') # 返回第一个 result1 = soup.select('a')[0] """ class选择器 : .className """ # 一层一层的进行选择,用 > 链接 即 > : 表示一个层级 # 输出 class = nr_zt 下ul下的li下的a标签集合 a = soup.select('.nr_zt > ul > li > a') # 多个层级关联,使用 空格。 # 输出 class= 'nr_zt' 下的a标签集合 b = soup.select('.nr_zt a') """ id选择器: # idName """ result = soup.select('#star') # 经过href属性查找,返回列表 soup.select('a[href="zhengshuang.html"]') # 获取对应标签中img标签的src值 a = soup.select('a[href="zhengshuang.html"]')[0] print(a.img['src']) # 5940f2cd6b759.jpg
以上就是bs4的经常使用操做代码,实际上在具体的爬虫过程当中,匹配的方式比较灵活,因此你们也不用能够的去背,只须要记住其原理便可。