使用最基本的网页爬取通用框架:
# url为要爬取的网址,函数返回爬取网址的网页内容
def getHTMLText(url):
try:
r = requests.get(url,timeout=30)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
最好大学网首页
软科最好大学排名2019
软科中国最好学科排名
其中,我们重点浏览 软科中国最好学科排名 的网站,观察其每一学科排名网址的编排规律,如下:
软件工程:http://www.zuihaodaxue.cn/BCSR/ruanjiangongcheng2019.html
土木工程:http://www.zuihaodaxue.cn/BCSR/tumugongcheng2019.html
石油与天然气工程:http://www.zuihaodaxue.cn/BCSR/shiyouyutianranqigongcheng2019.html
等等
可以发现,各学科对应的网址之间存在这样的规律:
都是由 http://www.zuihaodaxue.cn/BCSR/ + str(学科全名拼音) + 2019.html 组合而成。。
为了获取各学科的大学排名情况,我们可以设置外部输入想要查询的 学科 全名,然后通过Python的拼音库将输入的汉字转化为拼音,然后拼接成对应学科专业的网址(此部分将于程序开始处处理,此处略作说明):
# 拼接想要查询的学科对应的网址
s = input("请输入您想要咨询的专业学科全名:")
ss = ""
# 通过python的pypinyin库,解决汉字转成拼音的问题
for i in lazy_pinyin(s):
ss = ss + str(i)
surl = "http://www.zuihaodaxue.cn/BCSR/" + ss + "2019.html"
网页内容分析:
该学科在全国各高校的排名的网页解析:软科中国最好学科排名
如图(该示例为软件工程学科排名情况),通过观察HTML网页的结构,我们选用 Beautiful Soup库 对网页进行解析:
# slist存储该学科在全国各高校的排名情况,包括2019学科排名,2018学科排名,百分位段,学校名称,学科评分信息
# binfo存储该学科博士点院校
# zinfo存储该学科重点学科院校
# shtml为获取的该学科网页
def ranksList(slist,binfo,zinfo,shtml):
soup = BeautifulSoup(shtml,"html.parser")
for tr in soup.find('tbody').children:
if isinstance(tr,bs4.element.Tag):
tds = tr('td')
if len(tds)<7:
continue
slist.append([tds[0].string,tds[1].string,tds[2].string,tds[3].string,tds[-1].string])
for img in tr.find_all(title=re.compile("一级学科博士学位授权点")):
if isinstance(img,bs4.element.Tag):
binfo.append([tds[0].string,tds[1].string,tds[2].string,tds[3].string,tds[-1].string])
for img in tr.find_all(title=re.compile("一级学科国家重点学科")):
if isinstance(img,bs4.element.Tag):
zinfo.append([tds[0].string,tds[1].string,tds[2].string,tds[3].string,tds[-1].string])
中国最好大学排名的网页解析:软科最好大学排名2019
如上图,同样使用 Beautiful Soup库 对网页进行解析:
# alist存储学校排名情况,包括学校排名,学校名称,所在省市
# ahtml为获取的学校排名网页
def rankaList(alist,ahtml):
soup = BeautifulSoup(ahtml,"html.parser")
for tr in soup.find('tbody').children:
if isinstance(tr,bs4.element.Tag):
tds = tr('td')
alist.append([tds[0].string,tds[1].string,tds[2].string])
上述过程中,我们获取了 指定(这个指定由使用者自己输入)学科在全国各高校的排名 和 中国最好大学排名,接下来我们将这两个数据列表组合起来,构成一个新列表:使其既有 指定学科 的排名信息,又有 该学科对应大学的综合排名及所在地信息。。
# slist存储该学科在全国各高校的排名情况,包括2019学科排名,2018学科排名,百分位段,学校名称,学科评分信息
# alist存储学校排名情况,包括学校排名,学校名称,所在省市
# result为结果列表
def makeGroup(alist,slist,result):
for s in slist:
# 构造单个列表,存储一个“元素”
data = [0]*7
data[0],data[1],data[2],data[3],data[4] = s[0],s[1],s[2],s[3],s[-1]
for a in alist:
if a[1] == data[3]:
data[5],data[6] = a[0],a[2]
# 处理暂无数据的部分院校情况
if data[1] is None:
data[1] = 0
result.append(data)
特别需要注意的是,有些院校的部分数据为空,如下图,需特殊处理(否则无法对该部分数据进行处理)
—》因为爬虫获取该部分的数据为 NoneType。。。
这一部分主要内容就是对获得数据进行格式化输出处理:
# result为最终结果列表
def printList(result):
tplt = "{0:^10}\t{1:^10}\t{2:^10}\t{3:{7}^10}\t{4:^10}\t{5:^10}\t{6:^10}"
print(tplt.format("2019学科排名","2018学科排名","百分位段","学校名称","学科评分","大学排名","所在省市",chr(12288)))
for r in result:
print(tplt.format(r[0],r[1],r[2],r[3],r[4],r[5],r[6],chr(12288)))
特殊打印(此处我特别打印了查询学科江西省该院校的排名情况,/(ㄒoㄒ)/~~;若需改为其他省,只需将‘江西’改变即可):
def printJXList(result):
tplt = "{0:^10}\t{1:^10}\t{2:^10}\t{3:{6}^10}\t{4:^10}\t{5:^10}"
print(tplt.format("2019学科排名","2018学科排名","百分位段","学校名称","学科评分","大学排名",chr(12288)))
for r in result:
if r[6] == '江西':
print(tplt.format(r[0],r[1],r[2],r[3],r[4],r[5],chr(12288)))
设置改查询过程可多次查询:
def main():
while(input("查询请摁任意键,然后回车,退出请直接回车:")):
s = input("请输入您想要咨询的专业学科全名:")
ss = ""
for i in lazy_pinyin(s):
ss = ss + str(i)
alist = []
slist = []
result = []
binfo = []
zinfo = []
aurl = "http://www.zuihaodaxue.cn/zuihaodaxuepaiming2019.html"
surl = "http://www.zuihaodaxue.cn/BCSR/" + ss + "2019.html"
ahtml = getHTMLText(aurl)
rankaList(alist,ahtml)
'''
print(alist) # 查看是否获取所有大学信息(排名,学校名称,所在省市)
'''
yn = requests.get(surl,timeout=30)
# 检测输入是否正确
if yn.status_code == 404:
print("请输入正确或者完整的专业学科名称再尝试咨询!!")
print()
continue
shtml = getHTMLText(surl)
ranksList(slist,binfo,zinfo,shtml)
'''
print(slist) # 查看是否获取软件工程学科所有大学信息(2019学科排名,2018学科排名,百分位段,学校名称,学科评分)
'''
makeGroup(alist,slist,result)
'''
print(result) # 查看最终数据
'''
print()
print("{:^90}".format("江西省该学科院校排名信息"))
print()
printJXList(result)
print()
print("注:以下的'0'均表示暂无数据!!* 排名相同的学校按校名拼音顺序排列!!")
print()
print("{:^90}".format("全国该学科院校排名信息"))
print()
printList(result)
print()
print("其中博士点院校有"+str(len(binfo))+"所!!! 一级学科国家重点学科仅有"+str(len(zinfo))+"所,分别为:",end='')
for i in zinfo:
print(str(i[3])+" ",end='')
print()
print()
执行:
if __name__=="__main__":
main()
print()加的有点点难看,但是为了输出好看也莫得办法啦!!
此外,需要使用到的python库:
import requests
from bs4 import BeautifulSoup
from pypinyin import pinyin, lazy_pinyin
import bs4