汐ya~ 2022-03-24 21:35 采纳率: 87.8%
浏览 153
已结题

python爬取软科排名,匹配不到数据

问题遇到的现象和发生背景

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)



img

我的解答思路和尝试过的方法
我想要达到的结果
  • 写回答

1条回答 默认 最新

  • 木易荆岑 2022-03-25 11:41
    关注

    我这里是可以正常运行的

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月27日
  • 已采纳回答 3月27日
  • 修改了问题 3月24日
  • 创建了问题 3月24日

悬赏问题

  • ¥15 在若依框架下实现人脸识别
  • ¥15 网络科学导论,网络控制
  • ¥100 安卓tv程序连接SQLSERVER2008问题
  • ¥15 利用Sentinel-2和Landsat8做一个水库的长时序NDVI的对比,为什么Snetinel-2计算的结果最小值特别小,而Lansat8就很平均
  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同