爬取梨视频
分析阶段
爬取视频平台:梨视频
分析梨视频的视频请求方式
点击加载更多后,页面并没有刷新而视频渲染出来了,这说明是局部刷新,很有可能是Ajax请求。
查看网络Ajax请求
点击加载更多后,出现了Ajax请求,这时候需要靠猜,猜这个请求地址就是返回更多视频的地址。
测试Ajax请求地址
经过多次测试,发现filterlds、mrd字段不加也可以请求,剩余其他字段必须加,不加就无法正常请求。
经过多次测试,初步判断start字段是页码,0表示从第0个开始返回25个资源,其余字段目前无法判断,也不清楚有啥用但必须带上。
返回的是一堆HTML标签,每一个资源都用li标签包裹着。
实际有用URL:https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=1&start=0
查看视频元素
初步判断:很有可能是未播放时,使用图片代替,播放时,利用JS将真正的视频替换图片。
初步判断:既然使用JS将真正的视频替换图片,那么JS中可能有视频链接。
查找视频链接,发现视频是img标签代替着
尝试点击播放,发现视频不再是图片,而是替换为video标签,里面有视频的地址,使用浏览器直接访问该地址是有效的。
最终判断
最终排除JS有视频链接的可能【以前的梨视频在JS是能够直接看到的,但是改规则了。。。】
初步判断:播放视频时页面并没有刷新,判断播放视频时,JS通过Ajax请求得到的视频链接,后再替换图片。
当刷新网页时,就会出现一次Ajax请求,该请求中携带了 图片链接 和 视频链接。
访问图片链接是没问题的,但访问视频链接出现 404 Not Found,这说明这里的视频链接是有问题的。
对比两者视频链接的区别,规则不一致,1683819711986为系统unix时间戳,将时间戳替换为:【count-视频ID】 才是正确的视频链接。
# video标签里的视频链接
https://video.pearvideo.com/mp4/adshort/20200710/cont-1685265-15257383_adpkg-ad_hd.mp4
# Ajax请求里的视频链接
https://video.pearvideo.com/mp4/adshort/20200710/1683819711986-15257383_adpkg-ad_hd.mp4
最终判断:Ajax请求里的视频链接有问题,需要利用特定规则才可获得有效的视频链接。
爬取阶段
泄愤:梨视频以前爬起来很简单,现在规则改的有点恶心。但好心不负有心人,搞了一晚上搞出来了。
完整代码【闲太慢自己开多线程或者协程】
import requests
import re
number = 0
count = 0
while True:
while count < 25:
# 拿到有效的视频列表
url = 'https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=1&start=%s' % number
# 请求拿到response
response = requests.get(url=url)
li_list = '<a href="(.*)" class="vervideo-lilink actplay">'
# 正则匹配元素a标签里的视频ID,得到所有视频以列表存储
video_id_list = re.findall(li_list, response.text)
for video_id in video_id_list:
"""
# 测试阶段数据,拿到视频详细信息
# url = 'https://www.pearvideo.com/' + video_id
# response = requests.get(url=url)
"""
# 去除视频ID的video前缀,得到视频的数字ID
video_num = video_id.rsplit('_')[-1]
url = 'https://www.pearvideo.com/videoStatus.jsp?cnotallow=%s' % video_num
# 向后端服务器发送请求得到一串包含视频链接的json数据
# 请求时,后端服务器会校验请求头的user-agent以及referer信息,referer信息必须是该视频的详细信息地址当作上一次请求,否则后端会拒绝。
Video_response = requests.get(url=url, headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36',
'Referer': 'https://www.pearvideo.com/%s' % video_id
})
# 得到json数据反序列化为字典。
video_json = Video_response.json()
# 获取系统时间【unix时间戳】
systemTime = video_json.get('systemTime')
# 从字典中找到srcUrl关键字的value值,该value值就是视频地址
# 获取的视频地址并不是正确的,需要添加规则,也就是将系统时间替换为:cont-视频数字ID
video_url = video_json.get('videoInfo').get('videos').get('srcUrl').replace(systemTime, 'cont-%s' % video_num)
# 从视频地址中获取视频文件名字
video_name = video_url.rsplit('/', 1)[-1]
# 请求得到视频的response
video_response = requests.get(url=video_url)
print('开始下载:%s' % video_name)
with open(video_name, 'wb') as f:
# 将二进制数据一点一点写入本地
for line in video_response.iter_content():
f.write(line)
print('%s:下载成功' % video_name)
count += 1
else:
number += 1
count = 0