梨视频最热视频爬取源码

  1 # -*- ecoding: utf-8 -*-
  2 # @ModuleName: 2、梨视频最热视频爬取
  3 # @Function: 
  4 # @Author: merry
  5 # @Time: 2021/1/20 18:51
  6 import requests
  7 from lxml import etree
  8 from multiprocessing.dummy import Pool
  9 import random
 10 import os
 11 import time
 12 
 13 url = 'https://www.pearvideo.com/category_5'
 14 # 定义请求头
 15 headers = {
 16     'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'
 17 }
 18 # 获得当前页面所有数据
 19 response = requests.get(url, headers=headers).text
 20 # etree解析
 21 tree = etree.HTML(response)
 22 # 解析详情页面的url返回li标签列表
 23 div_list = tree.xpath('//ul[@id="listvideoListUl"]/li')
 24 # 定义一个视频列表用来存放所有视频的文件路径,文件名,视频真实地址的url
 25 video_list = []
 26 # 遍历list标签
 27 for li in div_list:
 28     # video_1716852  解析a标签的href熟悉获取详情页url
 29     viedeo_url = li.xpath('./div/a/@href')[0]
 30     # 获取视频的名称
 31     viedeo_name = li.xpath('./div/a/div[2]/text()')[0]
 32     # 1716852  分隔viedeo_url 得到一个数组,获取第一个元素得到数字ID
 33     viedeo_contID = str.split(viedeo_url, 'video_')[1]
 34     # 返回视频地址的url
 35     url = 'https://www.pearvideo.com/videoStatus.jsp'
 36     # 生成随机时间戳
 37     time_mrd = random.random()
 38     # 定义请求头,这个请求头需要传入一个上面解析到的viedeo_url
 39     headers = {
 40         'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36',
 41         'Referer': f'https://www.pearvideo.com/{viedeo_url}'
 42     }
 43     # 定义params参数,传入contId上面获取到的viedeo_contID,还需要传入一个mrd随机时间戳,上面已经生成time_mrd
 44     # 这两个参数和上面的请求头的内容是必须的,否则响应回来的数据提示页面不存在,错误的json
 45     params = {
 46         'contId': viedeo_contID,
 47         'mrd': time_mrd
 48     }
 49     # 请求视频地址的url,返回的是一个json的数据
 50     reponse = requests.get(url, headers=headers, params=params).json()
 51     # 使用字典的方式一次获取一个srcUrl的键值,这个地址不是真正的视频地址:如下
 52     ## 此地址是返回json地址    https://video.pearvideo.com/mp4/third/20210120/1611144446807-10008579-085440-hd.mp4   这个地址拿去浏览器你会发现404 notfound根本找不到这个视频
 53     #                                                                拼接部分cont-viedeo_url
 54     # 这是真实的视频地址       https://video.pearvideo.com/mp4/third/20210120/cont-1717106-10008579-085440-hd.mp4    这个真实地址是通过打开详情页面播放视频的时候抓包所获得
 55     # 通过对比你发现在真实地址最后一个斜杠后面的参数是 cont-1717106-10008579-085440-hd.mp4
 56     #                          而请求返回的地址是 1611144446807-10008579-085440-hd.mp4
 57     # 除了cont-1717106 和 1611144446807 不一样 其他都一样,说明有猫腻
 58     # 分析真实地址的cont-1717106  发现1717106 是前面参数viedeo_url请求到的url链接的后半部分数字,
 59     # 那么就需要截取字符串再将viedeo_url的数字部分和cont-进行拼接 得到类似cont-1717106-10008579-085440-hd.mp4这样的名称才是视频的真实地址
 60 
 61     # 从json中拿到假的视频url链接
 62     get_video_url = reponse['videoInfo']['videos']['srcUrl']
 63     # 获取需要替换的随机时间戳
 64     get_systemTime = reponse['systemTime']
 65     # 使用viedeo_contID拼接字符串cont-得到一个新的new_viedeo_contID
 66     new_viedeo_contID = 'cont-' + viedeo_contID
 67     # 替换假url中的随机时间戳为上面拼接好的new_viedeo_contID得到一个真实视频下载的url
 68     new_viedeo_url = str.replace(get_video_url, get_systemTime, new_viedeo_contID)
 69     print(f'\033[32m拼接新的URL   {new_viedeo_url}    完成')
 70     # 定义个字典,将文件路径,视频的名称和真实地址的url放在里面
 71     url_dict = {
 72         'file_path': './mp4/',
 73         'name': viedeo_name + '.mp4',
 74         'new_viedeo_url': new_viedeo_url
 75     }
 76     # 将上面的字典添加的列表中方
 77     video_list.append(url_dict)
 78 
 79 # 判断存放视频的文件夹是否存在,如果不存在则新建文件夹
 80 if not os.path.exists('./mp4'):
 81     os.mkdir('mp4')
 82 
 83 
 84 def get_video_data(dict):
 85     """
 86     :param dict: 得到真实视频的二进制数据并存入硬盘
 87     :return:
 88     """
 89     # 定义请求头
 90     headers = {
 91         'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36'
 92     }
 93 
 94     print(f'\033[31m开始下载{dict["name"]}')
 95     # 定义开始时间
 96     start_time = time.time()
 97     # 获取传入进来字典的new_viedeo_url,的真实视频地址的url获取二进制响应数据
 98     viedeo_content = requests.get(dict["new_viedeo_url"], headers=headers).content
 99     # 存放到硬盘,获取字典的路径和文件名
100     with open(dict["file_path"] + dict['name'], 'wb') as fp:
101         # 写入硬盘
102         fp.write(viedeo_content)
103         # 下载结束时间
104         end_time = time.time()
105         # 计算下载耗时
106         print(f'\033[32m下载   {dict["name"]}完成---------耗时:{int(end_time - start_time)}秒钟!')
107 
108 
109 # 获取video_list视频列表的长度,根据列表长度开启对应的多线程
110 viedeo_total = len(video_list)
111 # 定义线程池,传入列表长度
112 pool = Pool(viedeo_total)
113 # 传入get_video_data函数和可迭代对象video_list
114 pool.map(get_video_data, video_list)
115 print()
116 print(f'\033[31m 下载所有文件完成!文件存放路径为:./mp4')
 
posted @ 2021-01-21 09:49  Merry'blog  阅读(142)  评论(0编辑  收藏  举报