问题遇到的现象和发生背景 :
批量爬取某网站的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:
目的是判断是不是resp.get没有正常返回数据,思路如下:
既然说resp.get没有正常返回内容,那必定是title、audio_url, video_url这三个文本信息都取不到(因为三个数据都同一个resp.text里边),但是这时出现的结果更令我迷惑,只有标题有时是取不到的,另外两个数据每次都可以取到的。有人肯定又会说是我取标题的正则语法有问题,再强调一下,对于同一个标题有时可以取到有时取不到,所以不是正则语法的问题(以下是连续两次尝试的截图):
以下是我尝试的全部代码(再强调一下,对于报错卡住的地方,我都尝试单独爬过那一个,可以爬到,所以我的正则语法不存在问题。为防止发不出来有些地方以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没有正常返回内容)