开发环境
- Python版本:Python 3.6 / 3.8
- 代码编辑器:pycharm
模块
- requests、re
- pip install requests
知识点
- requests 的简单使用
- 正则表达式的简单使用
大概思路
一、数据来源分析
(比较重要, 只有当你找到数据来源的时候, 你才能通过代码去实现)
1、确定要爬取的内容 (梨视频)
2、利用开发者工具(F12 或者 鼠标右键点击检查 选择 network)进行抓包分析 (学爬虫, 写爬虫程序) 开发者工具 要会使用
当我们要爬取多个视频内容 数据内容 (要知道一个数据从哪里来的)
I、找到一个视频播放的url地址
II、找这个播放地址的来源 >>>> videoInfo
真实的播放地址
https://video.pearvideo.com/mp4/adshort/20210823/cont-1739485-15752387_adpkg-ad_hd.mp4
假的播放地址
https://video.pearvideo.com/mp4/adshort/20210823/1629873733405-15752387_adpkg-ad_hd.mp4
III、获取每一个视频的 ID 就可以获取所有视频的播放地址
二、代码实现步骤
- 发送请求 对于排行榜的url 发送请求
- 获取数据 获取网页源代码 (获取响应体的文本数据 response.text)
- 解析数据 提取想要的 视频ID 以及 视频标题
- 发送请求 需要把视频ID传入 相应的数据包里面
- 获取数据 获取json字典数据
- 解析数据 提取 假的播放地址
- 构建真实url地址
- 数据保存
- 进行多页/多个视频内容 爬取
要用到的模块统统安排上
import requests # 数据请求 第三方模块 pip install requests import re # 正则表达式模块 import pprint # 格式化输出模块 import time # 时间模块 import os # 文件操作的模块
创建一个文件夹存放下载的视频
filename = 'video\\' if not os.path.exists(filename): os.mkdir(filename)
特殊字符全部给它替换掉
def change_title(title): mode = re.compile(r'[\\\/\*\"\?\<\>\|]') new_title = re.sub(mode, '_', title) return new_title
客户端(浏览器)对于服务器发送请求, 服务器接收到请求之后, 会给客户端返回数据 (通过前端的页面渲染)
通过 python代码 对于服务器发送请求, 被反爬, 没有给你返回你想要的数据内容
需要把python代码进行伪装 : 请求头 headers
for page in range(10, 101, 10): url = f'https://www.pearvideo.com/popular_loading.jsp?reqType=1&categoryId=&start={page}&sort=4&mrd=0.985271587548759' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36' } response = requests.get(url=url, headers=headers) print(response.status_code)
返回的是响应体对象 200 状态码, 表示请求成功。
获取响应体的文本属性
response 返回的数据 和 elements 并不是一定是一样的
print(response.text)
解析数据 , re正则表达式, css选择器, xpath [哪一个最适合就那种]
.*? 匹配任意字符, \d+ 匹配多个数字,视频ID都是数字
正则表达式,匹配出来的内容,返回的是列表
video_ids = re.findall('<a href="video_(\d+)" class="popularembd actplay">', response.text) titles = re.findall('<h2 class="popularem-title">(.*?)</h2>', response.text)
我们都知道 如果要提取列表中每一个元素 是需要遍历 如果我们同时提取两个列表呢?
.zip 压缩包文件 zip(video_ids, titles) 返回是可迭代对象,可以遍历, for循环可以提取出来。
for video_id, title in zip(video_ids, titles): # video_id = i[0] # title = i[1] # print(video_id) # print(title) # 字符串格式化方法 '{video_id}'.format(video_id) new_title = change_title(title) link_url = f'https://www.pearvideo.com/videoStatus.jsp?contId={video_id}&mrd=0.8988491099054703' print(link_url)
Referer : 告诉服务器, 我们请求的url地址 是从哪里跳转过来的
headers_1 = { 'Referer': f'https://www.pearvideo.com/video_{video_id}', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36' } response_1 = requests.get(url=link_url, headers=headers_1)
print(response_1.json())
pprint.pprint(response_1.json())
对于json字典数据 可以直接根据键值对取值 根据冒号左边的内容 提取冒号右边的内容
src_url = response_1.json()['videoInfo']['videos']['srcUrl'] now_time = response_1.json()['systemTime']
replace 字符串替换的意思 就是 now_time 替换成 ‘cont-1739485’
video_url = src_url.replace(now_time, f'cont-{video_id}') print(video_url)
now_time = int(time.time() * 1000)
print(now_time)
print(src_url)
获取当前时间戳 直接替换掉
真实的播放地址
https://video.pearvideo.com/mp4/adshort/20210823/cont-1739485-15752387_adpkg-ad_hd.mp4
假的播放地址
https://video.pearvideo.com/mp4/adshort/20210823/1629873733405-15752387_adpkg-ad_hd.mp4
string_1 = ‘/’.join(src_url.split(’/’)[:-1])
string_2 = ‘-’.join(src_url.split(’-’)[1:])
video_url = string_1 + ‘/cont-’ + video_id + ‘-’ + string_2
print(video_url)
video_content = requests.get(url=video_url).content with open(filename + new_title + '.mp4', mode='wb') as f: f.write(video_content) print(title)
OK ,我们看看爬取结果
很多小伙伴因为没有好的学习资料或者遇到问题不能及时得到解决,导致自己学不下去,这里小编给大家准备了大量学习资料,都可以点上面的(蓝色点我领取)
Python 环境、pycharm编辑器/永久激活/python教程翻译插件
作者:静默虚空