从网页抓取视频(确定需求,我们要爬取梨视频下娱乐频道的最热视频)
优采云 发布时间: 2022-03-11 19:24从网页抓取视频(确定需求,我们要爬取梨视频下娱乐频道的最热视频)
确定需求,我们要爬梨视频下娱乐频道最热的视频
第一步获取起始url:/category_4,然后打开网站进行抓包分析
不难发现,我们需要的视频地址都在ul标签下的li标签中,使用xpath解析,得到所有的li标签。就个人而言,我认为 xpath 是最好的 html 解析工具。Beautifulsoup太复杂,解析方法太多,容易混淆,所以我的爬虫使用xpath来解析数据。
拿到li标签后,视频的url在li标签下第一个div下a标签的herf属性中,我们就得到了视频的地址,比如这个video_1730677
3.第二步是拼接网站,谁来拼接是个问题。如果用初始url拼接访问,在得到的响应中是找不到mp4的。
表示该地址不在静态网页中,则开始抓包分析
可以看到只有一个包,一点也不简单。点进去可以看到返回的数据里面有视频的下载地址,不过不要太高兴。视频的真实地址是/mp4/third/20210528/cont-1394-171325-hd.mp4,抓包是/mp4/third/20210528/89-125-hd.mp4,仔细一看,我发现两个url的最后一个'/'和最近的'-'之间的字符串不一样,其余的都是一样的。url中最后一个'/'和最近的'-'之间的字符串替换为cont-1730677,1730677是第一步得到的a标签属性,然后去掉video_。这里我用正则表达式替换了它
4.第三步,视频的假地址在这个网站/videoStatus.jsp?contId=1730677&mrd=0.59567的返回对象中,如果要发这个< @网站 requests 请求必须携带两个参数
countId和mrd,通过简单分析,我们知道countId是视频号,也就是上面的a标签属性去掉video_,mrd是0到1之间随机生成的数字,可以使用python的random.random来实现()。如果只携带这两个参数进行访问,仍然无法获取数据,需要在请求头中添加refer参数。因为我没有带这个参数,所以很长时间都拿不到数据。记住!
5.第四步,快乐下载,结果图
具体代码如下:
import requests
import os
from lxml import etree
import random
import time
import re
class PearVideo(): # 定义梨视频类
def __init__(self):
self.start_url = 'https://www.pearvideo.com/category_4'
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
def get_video_url(self): # 获取单个视频的地址和countId
resp = requests.get(self.start_url, headers=self.headers).text
tree = etree.HTML(resp)
li_list = tree.xpath('.//ul[@class="listvideo-list clearfix"]/li')
video_urls = []
countId_list = []
video_names = []
for li in li_list:
video_url = li.xpath('./div[1]/a/@href')[0]
countId = video_url.split('_')[-1]
countId_list.append(countId)
video_name = li.xpath('.//div[@class="vervideo-title"]/text()')[0]
mrd = random.random()
video_url = 'https://www.pearvideo.com/videoStatus.jsp?contId={}&mrd={}'.format(countId, mrd)
video_urls.append(video_url)
video_names.append(video_name)
return video_urls, countId_list, video_names
def get_download_url(self): # 获取视频的真实下载地址,请求头中要携带refer参数,不然得不到想要的json数据
video_urls, countId_list, video_names = self.get_video_url()
download_urls = []
for url, countId in zip(video_urls, countId_list):
resp = requests.get(url, headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'Referer': 'https: // www.pearvideo.com / video_{}'.format(countId)
}).json()
time.sleep(1)
# print(resp)
download_url = resp['videoInfo']['videos']['srcUrl']
download_url = re.sub('/[0-9]+-', '/cont-{}-'.format(countId), download_url)
# print(download_url)
# time.sleep(1)
download_urls.append(download_url)
# print(download_urls)
return download_urls, video_names
def download_video(self): # 视频的保存
download_urls, video_names = self.get_download_url()
# print(download_urls)
filename = 'D://pearvideo' #视频保存在d盘的pearvideo文件夹下
if not os.path.exists(filename):
os.mkdir(filename)
index = 0
for url in download_urls:
with open('{}/{}.mp4'.format(filename, video_names[index]), mode='wb') as f:
resp = requests.get(url, headers=self.headers).content
# print(resp)
f.write(resp)
time.sleep(1)
index += 1
if __name__ == '__main__':
pearvideo_spider = PearVideo()
pearvideo_spider.download_video()
别说手动也可以(不过是真的),写这么多代码不是比手动更好吗?哈哈哈!看看我的下一个分析!
总结一下我的不足:我只爬取了静态网页中的四个视频,其余视频都是通过ajax向服务器请求获取的,而不是简单的改变页面的值。这个问题我没有仔细研究过;i 本爬虫为单线程爬虫,视频下载速度可能较慢。可以考虑使用多线程,速度可能会更快,但是我对自己的多线程编程水平没有信心(四个视频一个线程就够了);需要注意的是,如果要获取视频下载地址,requests请求必须携带refer参数。因为我没有带这个参数,所以弄了半天也拿不到。
随附的:
经过我的研究,爬多页其实很容易。当我打开抓包工具继续往下滑,可以看到本地有很多请求发送到服务器,如下:
/category_loading.jsp?reqType=5&categoryId=4&start=12&mrd=0.36427441062670063&filterIds=1730677,1730635,1730509,1730484,1728846,1730305,1730384,1730381,1730338,1729112,1729081,1729048
/category_loading.jsp? reqType = 5&的categoryId = 4&启动= 264&MRD = 0. 67719&filterIds = 1730677,1730635,1730509,1714315,1714259,1714097,1713907,1713860,1713859,1713753,1713719,1713572,1713571,1713361 ,1713304
经过简单分析,要得到分页后的视频数据,只需要改变上面网站的start参数即可。可以从1开始,每页有12个视频,不过我没试过。如果你想尝试,你可以做到。爬取整个网站的视频并不容易,但是这么大的数据量需要多线程和数据库知识。努力工作才能进步!
这是我在 知乎 中的第二篇文章 文章(另一篇水文文章,但我仍然喜欢在没有技术的情况下写作)。记录你自己的爬虫成长史!也希望和其他喜欢爬虫的人分享爬虫学习资料,一起讨论技术。很喜欢张宇的话:不忘,必有回响!