问题遇到的现象和发生背景
python爬取软科排名,只有生成一个排名,其他匹配不到数据
应该是那个正则表达式indData出现错误
请问怎么修改呀
[如果可以帮忙看下代码有没有哪里不好,需要优化呀]
问题相关代码,请勿粘贴截图
import re #正则表达式 匹配
import requests
import csv
import os
list_all=['arwu','bcur','rtugc','grsssd']
#中国最好大学排名,世界大学学术排名,中国两岸四地大学排名,全球体育类院系学术排名
#不同排名
def get_text(list,year):
url = "https://www.shanghairanking.cn/_nuxt/static/1647508426/rankings/{}/{}/payload.js".format(list,year)
print(url)
headers = {
'Referer': 'https://www.shanghairanking.cn/rankings/{}/{}'.format(list,year),
'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/93.0.4577.63Safari/537.36Edg/93.0.961.38'
}#防反爬虫
response = requests.get(url, headers=headers)#向网站发起请求,并获取响应对象参数
return response.text
def get_dict_value(key):
try:
result = dict_value[key].replace('"', "")
except:
result = key.replace('"', "")
return result
def printUnivList(ulist, year):
if os.path.exists('./{}'.format(year))==False :
os.mkdir('./{}'.format(year))#目录不存在则创建目录对应一个年份
if list=="bcur":
f = open('./{}/{}中国大学排名.csv'.format(year, year), 'w', encoding='utf-8', newline="")
csv_writer = csv.writer(f)
csv_writer.writerow(["排名", "学校名称", "省市", "类型", "总分", "办学层次"])#表头
csv_writer.writerows(ulist) # 多行写入列表
if list == "arwu":
f = open('./{}/{}世界大学学术排名.csv'.format(year, year), 'w', encoding='utf-8', newline="")
csv_writer = csv.writer(f)
csv_writer.writerow(["排名", "学校名称", "国家/地区", "国家/地区", "总分", "校友获奖"]) # 表头
csv_writer.writerows(ulist) # 多行写入列表
if list == "rtugc":
f = open('./{}/{}世界大学学术排名.csv'.format(year, year), 'w', encoding='utf-8', newline="")
csv_writer = csv.writer(f)
csv_writer.writerow(["排名", "学校名称", "国家/地区", "国家/地区", "总分", "校友获奖"]) # 表头
csv_writer.writerows(ulist) # 多行写入列表
if list == "grsssd":
f = open('./{}/{}世界大学学术排名.csv'.format(year, year), 'w', encoding='utf-8', newline="")
csv_writer = csv.writer(f)
csv_writer.writerow(["排名", "学校名称", "国家/地区", "国家/地区", "总分", "校友获奖"]) # 表头
csv_writer.writerows(ulist) # 多行写入列表
f.close()
for list in list_all:
for year in range(2003, 2022):#循环从2003至2022年
res_str = get_text(list,str(year))#获得对应年份的源代码,str(year)将其作为字符串
if list=="bcur":
repx = re.compile(r'univNameCn:"(.*?)",province:(.*?),univCategory:(.*?),score:(.*?),ranking:.*?,indData:{"\d+?":(.*?),"')
if list=="arwu":
repx = re.compile(r'univNameCn:"(.*?)",univUp.*?region:(.*?),regionRanking:(.*?),score:(.*?),indData:{"\d+?":(.*?),"')
if list=="rtugc":
repx = re.compile(r'univNameCn:"(.*?)",univUp.*?region:(.*?),regionRanking:(.*?),score:(.*?),indData:{"\d+?":(.*?),"')
if list=="grsssd":
repx = re.compile(r'univNameCn:"(.*?)",univUp.*?region:(.*?),regionRanking:(.*?),score:(.*?),indData:{"\d+?":(.*?),"')
hash_str = repx.findall(res_str, re.S)#re.s可匹配换号符
#正则表达式匹配对应数据compile()与findall()一起使用,返回一个列表
parameter = re.findall(r'}\((.*?)\)\)\);', res_str)
if parameter==[]:
continue
parameter = re.findall(r'}\((.*?)\)\)\);', res_str)[0].replace('"', "").split(',')
# replace去掉双引号,split用,将字符串分隔成列表
parameter_name = re.findall(r'\(function\((.*?)\){', res_str)[0].split(",")
dict_value = dict(zip(parameter_name, parameter))
#将parameter_name, parameter合并为一个字典
res_list = []
for j in range(len(hash_str)):
i = hash_str[j]
rank = j + 1 # 排名
name = i[0] # 校名
country = get_dict_value(i[1]) # 国家
regional_ranking = get_dict_value(i[2]) # 地区排名
score = get_dict_value(i[3]) # 成绩
alumni_award = get_dict_value(i[4]) # 校友获奖
print(rank, name, country, regional_ranking, score, alumni_award)
res_list.append([rank, name, country, regional_ranking, score, alumni_award])
#将一所大学全部数据放入一个列表里
if res_list !=[]:
printUnivList(res_list, year)