法学僧转行程序猿 2022-05-25 19:20 采纳率: 60%
浏览 153
已结题

批量爬取数据中报错list index out of range(索引本身没问题)怎么办

问题遇到的现象和发生背景 :
批量爬取某网站的MP4文件,在写代码过程中,对存在列表索引的地方都专门做了print测试,测试结果都正常,完全不存在list=[]或者list=[1,2,3]而我请求list[3]这样的情况,但是将代码整体运行时,总是报错list index out of range,而且每次报错的时间都不一样,有时保存三个MP4文件后报错,有时保存七个MP4文件时报错,也有一次直接连第一个MP4文件都没保存下来就报错了,报错如下(报错内容每次都是这些,一个字母都没变):

D:\python\python.exe C:/Users/PycharmProjects/尝试/临时试验.py
Traceback (most recent call last):
  File "C:/Users/PycharmProjects/尝试/临时试验.py", line 73, in <module>
    main(bv_id=bvid)
  File "C:/Users/PycharmProjects/尝试/临时试验.py", line 56, in main
    video_info = get_videoinfo(url=laosepi)
  File "C:/Users/PycharmProjects/尝试/临时试验.py", line 23, in get_videoinfo
    title = re.findall('<h1 id="video-title" title="(.*?)" class="video-title">', resp.text)[0].replace(' ', '')
IndexError: list index out of range

Process finished with exit code 1

表面上看,直接原因就是 title = re.findall……这个正则语法的问题,但是对于报错的,我都用同样的正则语法单独拿出来打印过对应标题,是可以取到的,所以正如下面某位答主所言,根本原因可能出在requests.get上,有时不能正常返回数据,根据以往经验,考虑到可能是对于频繁请求有反爬机制,于是加入了time模块,在resp = get_resp(url)后边添加了time.sleep(3),测试发现报错的时间还是随机,同一个标题有时可以取到有时就取不到。
于是再次尝试修改,将取不到title的都命名为000:

img

目的是判断是不是resp.get没有正常返回数据,思路如下:
既然说resp.get没有正常返回内容,那必定是title、audio_url, video_url这三个文本信息都取不到(因为三个数据都同一个resp.text里边),但是这时出现的结果更令我迷惑,只有标题有时是取不到的,另外两个数据每次都可以取到的。有人肯定又会说是我取标题的正则语法有问题,再强调一下,对于同一个标题有时可以取到有时取不到,所以不是正则语法的问题(以下是连续两次尝试的截图):

img


img

以下是我尝试的全部代码(再强调一下,对于报错卡住的地方,我都尝试单独爬过那一个,可以爬到,所以我的正则语法不存在问题。为防止发不出来有些地方以abcdefg代替)

import requests
import re
import json  
import subprocess  
import os 
import time


def get_resp(url):
    headers = {
        'referer': 'abcdefg',
        'user-agent': 'abcdefg'
    }
    resp = requests.get(url=url, headers=headers)
    return resp


def get_videoinfo(url):
    resp = get_resp(url)
    title = re.findall('<h1 id="video-title" title="(.*?)" class="video-title">', resp.text)[0].replace(' ', '')
    video_data = re.findall('<script>window.__playinfo__=(.*?)</script>', resp.text)[0]

    json_data = json.loads(video_data)
    audio_url = json_data['data']['*****']['audio'][0]['****']
    video_url = json_data['data']['*****']['video'][0]['****']
    video_info = [title, audio_url, video_url]
    time.sleep(1)
    return video_info


def save(title, audio_url, video_url):
    audio_content = get_resp(url=audio_url).content
    video_content = get_resp(url=video_url).content
    with open('picture\\' + title + '.mp3', 'wb') as f:
        f.write(audio_content)
    with open('picture\\' + title + '.mp4', 'wb') as f:
        f.write(video_content)
    print('保存完成')
    ffmpeg = f'ffmpeg -i picture\\{title}.mp4 -i picture\\{title}.mp3 -c:v copy -c:a aac -strict experimental picture//{title}output.mp4'
    subprocess.run(ffmpeg, shell=True)
    os.remove(f'picture\\{title}.mp4')
    os.remove(f'picture\\{title}.mp3')
    print(f'第{n}个合成成功')
    time.sleep(1)


def main(id):
    laosepi = f'abcdefg/{id}'
    video_info = get_videoinfo(url=laosepi)
    save(video_info[0], video_info[1], video_info[2])


# 函数入口
if __name__ == '__main__':
    n=1
    for page in range(1,6):
        index_url = f'abcdefg{page}abcdefg'
        json_data = get_resp(url=index_url).json()
        id_list = [i['****'] for i in json_data['data']['list']['****']]
        for every_id in id_list:
            main(id=every_id)
            n+=1
            time.sleep(1)

我这个情况到底该怎么解决?如果有有效办法,测试成功后立即采纳(再强调一下:其一、对于报错卡住的地方,我都尝试单独爬过那一个,可以爬到,所以排除我的正则语法不正确的问题;其二、三个数据都在同一个requests得到的resp.text里边,通过上面的尝试,说明只有title有时是取不到的,其他两个数据每次都能取到,所以我认为能够排除requests没有正常返回内容

  • 写回答

2条回答 默认 最新

      报告相同问题?

      相关推荐 更多相似问题

      问题事件

      • 系统已结题 6月5日
      • 已采纳回答 5月28日
      • 赞助了问题酬金5元 5月26日
      • 修改了问题 5月26日
      • 展开全部

      悬赏问题

      • ¥20 想问问RequestMapping能找到controller,但controller中的方法却不起作用
      • ¥15 计算机组成原理设计八位理论计算机整机系统
      • ¥15 把这个迷宫问题代码修改一下
      • ¥15 工具变量 时间序列相关问题
      • ¥15 正弦波的峰值查找算法
      • ¥15 关于lwip的pbuf数据提取问题
      • ¥50 请求关于BBS数据集的资源分享
      • ¥15 设计一份接口自动化测试报告
      • ¥15 手机安装kali后ifconfig 提示错误
      • ¥15 用C++求矩阵的特征值