聚焦爬虫:爬取页面中指定的页面内容
数据解析分类:正则、bs4、xpath(重点)
数据解析原理:
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是解析、遍历、维护“标签树”的功能库
四种解析类:
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–可能有注释信息
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
soup.prettify()–能够为html文本的标签和内容增加换行符,也可以对每个标签进行处理
from bs4 import BeautifulSoup
soup = BeautifulSoup(demo,"html.parser")#解析后的内容
soup.prettify()
print(soup.prettify())
print(soup.a.prettify()) #对于a标签进行处理
html—超文本标记语言hyper text markup language
超文本—声音,图像,视频
1,XML --扩展标记语言
XML属于是xtml发展过来的
2,JSON --Java语言中面向对象信息的一种表达形式
json使用有类型的键值对将信息组织起来
如果值的地方有多个信息与键相对应,我们使用方括号
也可以把一个键值对作为值的部分,放入另一个键值对中,采样大括号进行嵌套
好处:对于Java语言,可以直接使用,是的程序大大简化
3,YAML
使用无类型键值对,在键值对中不增加任何符号或者相关的类型标记
其中 - 表示并列 # 表示注释 键值对之间可以嵌套
XML —使用尖括号标签—来表达信息
JSON — 使用有类型的键值对
YAML — 使用无类型键值对
下面用这三种形式来表现同一信息
XML实现:
XML特点:有效信息并不高,大多信息被标签占用
JSON实现:
特点:键值对都用到了双引号
YAML实现:
三种信息标记形式的比较:
三者使用情形:
方法一:完整解析信息的标记形式,再提取关键信息。
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"))
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")
bs4解析是python独有的,正则表达式可以用于其他语言
数据解析原理:1,标签定位 2,提取标签、标签属性中存储的数据值
bs4解析原理:
环境安装:
pip install bs4/lxml
pip install lxml
如何实例化BeautifulSoup对象:
提供的用于数据解析的方法和属性:
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'))#类选择器
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)