目录标题
- 数据解析
 - 1、BeautifulSoup库
 - 1.1 BeautifulSoup库入门
 - 1.1.1 BeautifulSoup类的基本元素:
 - 1.1.2 基于bs4库的HTML内容遍历方法
 - 1.1.3 基于bs4库的HTML格式化和编码
 
- 1.2 信息组织和提取方法
 - 1.2.1 信息标记的三种形式:xml,json,yaml
 - 1.2.2 三种信息标记形式的比较
 - 1.2.3 信息提取的一般方法
 
- 1.3 bs4解析
 
- 2、bs库案例:
 - 2.1 中国大学排名爬虫
 
数据解析
聚焦爬虫:爬取页面中指定的页面内容
 数据解析分类:正则、bs4、xpath(重点)
 数据解析原理:
- 进行指定标签的定位
 - 标签或者标签对应属性中存储数据值的提取
 
1、BeautifulSoup库
1.1 BeautifulSoup库入门
Beautiful soup库:能够对html 或xml进行解析,并提取其中的信息
 安装:pip install beautifulsoup4
 查看源代码:
 法1,手动右击,获取源代码
 法2,用request库获取
import requests
r = requests.get("http://python123.io/ws/demo.html")
r.text#即显示源代码
demo = r.text
from bs4 import BeautifulSoup
soup = BeautifulSoup(demo,"html.parser")#进行熬汤
print(soup.prettify()) #成功打印,即解析正确
 
BeautifulSoup的使用:
 两个参数:第一个html格式的信息,第二个解析器
 
 BeautifulSoup是解析、遍历、维护“标签树”的功能库
 四种解析类:
 
1.1.1 BeautifulSoup类的基本元素:

 应用:
from bs4 import BeautifulSoup
r = requests.get("http://python123.io/ws/demo.html")
r.text#即显示源代码
demo = r.text
soup = BeautifulSoup(demo,"html.parser")#解析后的内容
soup.title  #标签内容,左上方内容
tag = soup.a  #a标签即链接标签的内容
print(tag)
soup.a.name  #获取标签名字
soup.a.parent.name  #获取父标签名字
tag.attrs #标签a的属性,打印出一个字典
tag.attrs['class'] #a属性中class的值
type(tag.attrs) #标签属性的类型--字典
type(tag)  #标签的类型---bs4中类型
soup.a.string #a标签的字符串信息
type(soup.a.string) #字符串类型---bs4中类型
 
sooup.a----获得a标签
 a.name—获得标签a的名字
 a.sttrs—获得标签属性,返回一个字符串
 a.string --标签的字符串
 a.comment–可能有注释信息
 
1.1.2 基于bs4库的HTML内容遍历方法
html信息:
 
 将html换成树形结构:
 
 三种遍历方式:下行遍历、上行遍历、平行遍历
标签树的下行遍历:
 
 content返回列表,其他两个都是迭代类型,需要用在循环中
soup = BeautifulSoup(demo,"html.parser")
soup.head
soup.head.contents #输出是列表类型
soup.body.contents
len(soup.body.contents)
 
标签树的上行遍历:
 
soup = BeautifulSoup(demo,"html.parser")
soup.title.parent  #title标签的父亲
soup.html.parent #html标签的父亲,因为html是最高级的,所以其父亲是他本身
soup.parent #soup的父亲返回空
 
对a标签的所有前辈的名字进行打印:
 
 可能会遍历到soup本身,但soup没有父标签,所以需要判断一下
标签树的平行遍历:
 
 next_siblings和previous_siblings用在循环中
 平行遍历发生在同一个父节点下的各节点之间
soup = BeautifulSoup(demo,"html.parser")
soup.a.next_sibling   #a标签的下一个平行节点
soup.a.next_sibling.next_sibling  #a标签的下一个平行节点的再下一个
soup.a.previous_sibling   #a标签的前一个平行节点
soup.a.previous_sibling.previous_sibling
 

 总结
 
1.1.3 基于bs4库的HTML格式化和编码
soup.prettify()–能够为html文本的标签和内容增加换行符,也可以对每个标签进行处理
from bs4 import BeautifulSoup
soup = BeautifulSoup(demo,"html.parser")#解析后的内容
soup.prettify()
print(soup.prettify())
print(soup.a.prettify()) #对于a标签进行处理
 
1.2 信息组织和提取方法

 html—超文本标记语言hyper text markup language
 超文本—声音,图像,视频
1.2.1 信息标记的三种形式:xml,json,yaml
1,XML --扩展标记语言
 
 
 XML属于是xtml发展过来的
2,JSON --Java语言中面向对象信息的一种表达形式
 json使用有类型的键值对将信息组织起来
 如果值的地方有多个信息与键相对应,我们使用方括号
 也可以把一个键值对作为值的部分,放入另一个键值对中,采样大括号进行嵌套
 
好处:对于Java语言,可以直接使用,是的程序大大简化
3,YAML
 使用无类型键值对,在键值对中不增加任何符号或者相关的类型标记
 其中 - 表示并列 # 表示注释 键值对之间可以嵌套
 
 
1.2.2 三种信息标记形式的比较
XML —使用尖括号标签—来表达信息
 JSON — 使用有类型的键值对
 YAML — 使用无类型键值对
下面用这三种形式来表现同一信息
 XML实现:
 XML特点:有效信息并不高,大多信息被标签占用
 
JSON实现:
 特点:键值对都用到了双引号
 
 YAML实现:
 
 三种信息标记形式的比较:
- XML 最早的通用学习标记语言,可扩展性好,但繁琐
 - JSON 信息有类型,适合程序处理,是javascript扩展而来的,比XML简洁
 - YAML 信息五类型,文本信息比例最高,即有效信息占比最多,可读性好
 
三者使用情形:
- XML Internet上的信息交互与传递
 - JSON 移动应用云端和节点的信息通信,无注释。主要用在程序对接口处理的地方
 - YAML 各类系统的配置文件,有注释易读,应用相对广泛
 
1.2.3 信息提取的一般方法
方法一:完整解析信息的标记形式,再提取关键信息。
 XML,JSON,YAML 需要标记解析器 例如:bs4库的标签树遍历
 优点:信息解析准确
 缺点:提取过程繁琐,速度慢
方法二:无视标记形式,直接搜索关键信息
 搜索
 对信息的文本查找函数即可
 优点:提取过程简洁,速度较快
 缺点:提取结果准确性与信息内容相关
方法三:融合方法:结合形式解析与搜索方法,提取关键信息—最好的
 需要标记解析器及文本查找函数
方法三案例:
from bs4 import BeautifulSoup
soup = BeautifulSoup(demo,"html.parser")  #soup中包含了整个HTML信息
for link in soup.find_all("a"):  #找a标签
	print(link.get("href"))
 
find_all的使用:
 
soup.find_all("a") #返回该文件中所有的a标签
soup.find_all(["a","b"]) #返回该文件中所有的a标签和b标签
soup.find_all(True) #参数写成true,返回文件中所有的标签信息
for tag in soup.find_all(True):
	print(tag.name) #打印出这个文档里的所有标签名称
 
#下面只打印出所有以b开头的标签
import re
for tag in soup.find_all(re.compile('b')):
	print(tag.name)
#p标签中含有course字符串的信息
soup.find_all('p','course')
#找出标签id=link1的标签元素
soup.find_all(id="link1")
 
find_all可以结合正则表达式一起使用
 两种等价形式:
 
1.3 bs4解析
bs4解析是python独有的,正则表达式可以用于其他语言
 数据解析原理:1,标签定位 2,提取标签、标签属性中存储的数据值
 bs4解析原理:
- 实例化一个Beautifulsoup对象,并且将页面源码数据加载到该对象中
 - 通过调用Beautifulsoup对象中相关属性或者方法进行标签定位和数据提取
 
环境安装:
 pip install bs4/lxml
 pip install lxml
如何实例化BeautifulSoup对象:
- 将本地的html文档中的数据加载到该对象中
fp = open(‘./test.html’,‘r’,encoding = ‘utf-8’)
soup = BeautifulSoup(fp,‘html’) - 将互联网上获取的页面源码加载到该对象中
page_text = response.text
soup = BeautifulSoup(page_text,‘html’) 
提供的用于数据解析的方法和属性:
- soup.tagName :返回html中第一次出现的tagname信息
 - soup.find():其中find(‘tagName’) 等同与soup.div ,只返回第一次出现的
 - soup.find():属性定位:print(soup.find(‘div’,class_ = ‘song’))
 - soup.find_all():符合要求的所有信息
 - select : select(‘某种选择器(id,class,)’)
 - 获取标签之间的文本数据:soup.a.text/string/get_text(),其中text/get_text():可以获取某一个标签中所有文本内容。string:只可以获取该标签下面直系的文本内容
 - 获取标签中属性值:soup.a[‘href’]
 
from bs4 import BeautifulSoup
if __name__ == "__main__":
	fp = open('./test.html','r',encoding = 'utf-8')
 	soup = BeautifulSoup(fp,'html')
 	print(soup.a) #只是返回第一次出现的a标签
 	print(soup.find('div'))
 	print(soup.select('.tang'))#类选择器
 
2、bs库案例:
2.1 中国大学排名爬虫
url:http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html
 https://www.shanghairanking.cn/rankings/bcur/2022
 程序输入:url 输出:大学排名输出
动态脚本信息–bs库还无法获取
进入网页–右键查看网络源代码–再查看一下robost协议(www.zuihaodaxue.cn/robots.txt)-网页不存在,即网站没做限制
 
import requests
from bs4 import BeautifulSoup
import bs4
def getHTMLText(url):  #输入url,输出URL的内容
	try:
		r = requests.get(url,timeout = 30)
		r.raise_for_status()
		r.encoding = r.apparent_encoding
		return r.text
	except:
		return ""
def fillUnivList(ulist,html):  #将一个HTML页面的关键数据放到一个list中
	soup = BesutifulSoup(html,'html.parser')
	for tr in soup.find('tbody').children:
		if isinstance(tr,bs4.element.Tag):
			tds = tr('td')
			ulist.append([tds[0].string],[tds[1].string],[tds[2].string])
	pass
def printUnivList(ulist,num):  #将ulist打印出来,num是将里面多少元素打印出来
	print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称","总分"))
	for i in range(num):
		u = ulist[i]
		print("{:^10}\t{:^6}\t{:^10}".format(u[0],u[1],u[2]))
	print("Suc"+str(num))
def main():  #主函数
	uinfo = []
	url = "http://www.zuihaodaxue.cn/zuihaodaxuepaiming2022.html"
	html = getHTMLText(url)
	fillUnivList(ulist,html)
	printUnivList(ulist,num)
 

 优化代码
 问题:中文字符对齐问题
 解决:中文字符不够时,不用西文字符的空格填充,而是用中文字符的空格进行填充chr(12288)
import requests
from bs4 import BeautifulSoup
import bs4
def getHTMLText(url):  #输入url,输出URL的内容
	try:
		r = requests.get(url,timeout = 30)
		r.raise_for_status()
		r.encoding = r.apparent_encoding
		return r.text
	except:
		return ""
def fillUnivList(ulist,html):  #将一个HTML页面的关键数据放到一个list中
	soup = BesutifulSoup(html,'html.parser')
	for tr in soup.find('tbody').children:
		if isinstance(tr,bs4.element.Tag):
			tds = tr('td')
			ulist.append([tds[0].string],[tds[1].string],[tds[2].string])
	pass
def printUnivList(ulist,num):  #将ulist打印出来,num是将里面多少元素打印出来
	tplt = "{0:^10}\t{1:^6}\t{2:^10}"
	print("tplt.format("排名","学校名称","总分",chr(12288)))
	for i in range(num):
		u = ulist[i]
		print(tplt.format(u[0],u[1],u[2],chr(12288)))
	print("Suc"+str(num))
def main():  #主函数
	uinfo = []
	url = "http://www.zuihaodaxue.cn/zuihaodaxuepaiming2022.html"
	html = getHTMLText(url)
	fillUnivList(ulist,html)
	printUnivList(ulist,num)
                

















