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

优采云 发布时间: 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个视频,不过我没试过。如果你想尝试,你可以做到。爬取整个网站的视频并不容易,但是这么大的数据量需要多线程和数据库知识。努力工作才能进步!

  这是我在 知乎 中的第二篇文章 文章(另一篇水文文章,但我仍然喜欢在没有技术的情况下写作)。记录你自己的爬虫成长史!也希望和其他喜欢爬虫的人分享爬虫学习资料,一起讨论技术。很喜欢张宇的话:不忘,必有回响!

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线