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

批量爬取数据中报错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条回答 默认 最新

  • 一切因为有你 2022-05-25 22:28
    关注
    你是这句报的错,
    title = re.findall('<h1 id="video-title" title="(.*?)" class="video-title">', resp.text)[0].replace(' ', '')
    说明你这个正则没有匹配。
    你把这句拆开看下,title1 肯定是空list
    
    title1 = re.findall('<h1 id="video-title" title="(.*?)" class="video-title">', resp.text)
    print(title1)
    if len(title1)>0:
        title=title1[0].replace(' ', '')
    else:
        print("没有匹配")
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

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

悬赏问题

  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题