最近看了北京理工大学嵩天老师关于爬取最好大学软科排名实例,由于视频比较久远,网页发生了很大的变化,所以我写一下我的思路,希望帮助大家
排名链接:https://www.shanghairanking.cn/rankings/bcur/2020
我们打开网页,查看页面源代码发现确实变化了很多,学校名称加上了超链接,所以学校的名字在a标签里,就提取学校名称需要改变
import requests
from bs4 import BeautifulSoup
import bs4
#先获得页面的html文本
def getHTMLText(url):
try:
r = requests.get(url)
r.raise_for_status() #失败的话获取异常
r.encoding = r.apparent_encoding
return r.text
except:
return "爬取异常"
#获取html中想要的信息到列表中
def fillUnivList(ulist, html):
soup = BeautifulSoup(html, "html.parser") #将获取的html转化成可读的形式
for tr in soup.find("tbody").children: #获得tbody标签的儿子节点
if isinstance(tr, bs4.element.Tag): #判断tr是否是标签
tds = tr.find_all('td')
names = tds[1].find('a').text #因为学校名称位于第二个td标签,所以是tds[1],而且名称位于a标签里,所以是获取td标签中a标签的文本内容
ulist.append([tds[0].text, names, tds[4].text]) #这里别忘了加[],我好几次就错这
#打印出获取的内容
def printUnivList(ulist, num):
tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}" #用于获取format内容的模板
print(tplt.format("排名","学校名称","总分",chr(12288))) #这里是为了消除中英的字符占的空位的差异,选择用中文的空白补齐
for i in range(num):
u = ulist[i]
#这里又和老师的不一样了,我们要获取的部分有很多空格,所以我们得消除空格,否则会报错以下错误:TypeError: unsupported format string passed to NoneType.__format__
ranking = u[0].strip() #我们用strip()函数来消除空格
uname = u[1].strip()
totalscores = u[2].strip()
print(tplt.format(ranking, uname, totalscores, chr(12288)))
#定义一个主函数
def main():
url = "https://www.shanghairanking.cn/rankings/bcur/2020"
ulist = []
html = getHTMLText(url)
fillUnivList(ulist, html)
printUnivList(ulist, 20) #这里输出前20的学校,可以改,但不能超过30,因为30后的排名要翻页,此代码并没有实现此功能
#运行程序
main()