抓取网页视频(确定需求,我们要爬取梨视频下娱乐频道的最热视频)

优采云 发布时间: 2021-10-12 19:34

  抓取网页视频(确定需求,我们要爬取梨视频下娱乐频道的最热视频)

  确定需求,我们要爬取梨视频下娱乐频道最热的视频

  

  第一步获取起始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的最后一个'/'和最近的'-'之间的字符串是不一样的,其余的是相同的。其实只是假的 用cont-1730677替换url的最后一个'/'和最近的'-'之间的字符串。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()

  不要说你可以手动完成(但这是真的)。写这么多代码不是比手工差吗?哈哈哈!看我接下来的分析!

  总结一下我的缺点:我只爬取了静态网页中存在的4个视频,其余的视频都是通过ajax请求服务器获取的,而不是简单的改变页面值。我没有仔细研究过这个问题;我这个爬虫是单线程爬虫,下载视频可能会比较慢,可以考虑用多线程,速度可能会快一些,但是我对自己的多线程编程水平没有信心(四个视频足够一个单线程);需要注意的是,如果要获取视频下载地址,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参数就可以得到分页的视频数据。可以从start as 1开始,每页有12个视频,不过我没试过。如果你想尝试,你可以做到。全站视频不易抓取,但如此庞大的数据量需要多线程和数据库知识。努力工作!

  这是我在知乎 中的第二篇文章(这是另一种水文学,我喜欢没有技术的写作)。记录自己的爬虫成长历程!也希望与其他喜欢爬虫的人分享爬虫学习资料,讨论技术。很喜欢张宇的一句话:忘不了,必有回音!

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线