python 抓取知乎指定回答下视频的方法


Posted in Python onJuly 09, 2020

前言

现在知乎允许上传视频,奈何不能下载视频,好气哦,无奈之下研究一下了,然后撸了代码,方便下载视频保存。

接下来以 猫为什么一点也不怕蛇? 回答为例,分享一下整个下载过程。

调试一下

打开 F12, 找到光标,如下图:

python 抓取知乎指定回答下视频的方法

然后将光标移动到视频上。如下图:

python 抓取知乎指定回答下视频的方法

咦这是什么?视野中出现了一条神秘的链接: https://www.zhihu.com/video/xxxxx,让我们将这条链接复制到浏览器上,然后打开:

python 抓取知乎指定回答下视频的方法

似乎这就是我们要找的视频,不要着急,让我们看一看,网页的请求,然后你会发现一个很有意思的请求(重点来了):

python 抓取知乎指定回答下视频的方法

让我们自己看一下数据吧:

{
	"playlist": {
		"ld": {
			"width": 360,
			"format": "mp4",
			"play_url": "https://vdn.vzuu.com/LD/05fc411e-d8e0-11e8-bb8b-0242ac112a0b.mp4?auth_key=1541477643-0-0-987c2c504d14ab1165ce2ed47759d927&expiration=1541477643&disable_local_cache=1",
			"duration": 17,
			"size": 1123111,
			"bitrate": 509,
			"height": 640
		},
		"hd": {
			"width": 720,
			"format": "mp4",
			"play_url": "https://vdn.vzuu.com/HD/05fc411e-d8e0-11e8-bb8b-0242ac112a0b.mp4?auth_key=1541477643-0-0-8b8024a22a62f097ca31b8b06b7233a1&expiration=1541477643&disable_local_cache=1",
			"duration": 17,
			"size": 4354364,
			"bitrate": 1974,
			"height": 1280
		},
		"sd": {
			"width": 480,
			"format": "mp4",
			"play_url": "https://vdn.vzuu.com/SD/05fc411e-d8e0-11e8-bb8b-0242ac112a0b.mp4?auth_key=1541477643-0-0-5948c2562d817218c9a9fc41abad1df8&expiration=1541477643&disable_local_cache=1",
			"duration": 17,
			"size": 1920976,
			"bitrate": 871,
			"height": 848
		}
	},
	"title": "",
	"duration": 17,
	"cover_info": {
		"width": 720,
		"thumbnail": "https://pic2.zhimg.com/80/v2-97b9435a0c32d01c7c931bd00120327d_b.jpg",
		"height": 1280
	},
	"type": "video",
	"id": "1039146361396174848",
	"misc_info": {}
}

没错了,我们要下载的视频就在这里面,其中 ld 代表普清,sd 代表标清, hd 代表高清,把相应链接再次在浏览器打开,然后右键保存就可以下载视频了。

代码

知道整个流程是什么样子,接下来撸代码的过程就简单了,这里就不过再做过多解释了,直接上代码:

# -*- encoding: utf-8 -*-

import re
import requests
import uuid
import datetime


class DownloadVideo:

  __slots__ = [
    'url', 'video_name', 'url_format', 'download_url', 'video_number',
    'video_api', 'clarity_list', 'clarity'
  ]

  def __init__(self, url, clarity='ld', video_name=None):
    self.url = url
    self.video_name = video_name
    self.url_format = "https://www.zhihu.com/question/\d+/answer/\d+"
    self.clarity = clarity
    self.clarity_list = ['ld', 'sd', 'hd']
    self.video_api = 'https://lens.zhihu.com/api/videos'

  def check_url_format(self):
    pattern = re.compile(self.url_format)
    matches = re.match(pattern, self.url)
    if matches is None:
      raise ValueError(
        "链接格式应符合:https://www.zhihu.com/question/{number}/answer/{number}"
      )
    return True

  def get_video_number(self):
    try:
      headers = {
        'User-Agent':
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
      }
      response = requests.get(self.url, headers=headers)
      response.encoding = 'utf-8'
      html = response.text
      video_ids = re.findall(r'data-lens-id="(\d+)"', html)
      if video_ids:
        video_id_list = list(set([video_id for video_id in video_ids]))
        self.video_number = video_id_list[0]
        return self
      raise ValueError("获取视频编号异常:{}".format(self.url))
    except Exception as e:
      raise Exception(e)

  def get_video_url_by_number(self):
    url = "{}/{}".format(self.video_api, self.video_number)

    headers = {}
    headers['Referer'] = 'https://v.vzuu.com/video/{}'.format(
      self.video_number)
    headers['Origin'] = 'https://v.vzuu.com'
    headers[
      'User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36'
    headers['Content-Type'] = 'application/json'

    try:
      response = requests.get(url, headers=headers)
      response_dict = response.json()
      if self.clarity in response_dict['playlist']:
        self.download_url = response_dict['playlist'][
          self.clarity]['play_url']
      else:
        for clarity in self.clarity_list:
          if clarity in response_dict['playlist']:
            self.download_url = response_dict['playlist'][
              self.clarity]['play_url']
            break
      return self
    except Exception as e:
      raise Exception(e)

  def get_video_by_video_url(self):
    response = requests.get(self.download_url)
    datetime_str = datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S")
    if self.video_name is not None:
      video_name = "{}-{}.mp4".format(self.video_name, datetime_str)
    else:
      video_name = "{}-{}.mp4".format(str(uuid.uuid1()), datetime_str)
    path = "{}".format(video_name)
    with open(path, 'wb') as f:
      f.write(response.content)

  def download_video(self):

    if self.clarity not in self.clarity_list:
      raise ValueError("清晰度参数异常,仅支持:ld(普清),sd(标清),hd(高清)")

    if self.check_url_format():
      return self.get_video_number().get_video_url_by_number().get_video_by_video_url()


if __name__ == '__main__':
  a = DownloadVideo('https://www.zhihu.com/question/53031925/answer/524158069')
  print(a.download_video())

结语

代码还有优化空间,这里面我只是下载了回答中的第一个视频,理论上应该存在一个回答下可以有多个视频的。如果还有什么疑问或者建议,可以多多交流。

以上就是python 抓取知乎指定回答下视频的方法的详细内容,更多关于python 抓取视频的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python 深入理解yield
Sep 06 Python
python中字典(Dictionary)用法实例详解
May 30 Python
Python socket网络编程TCP/IP服务器与客户端通信
Jan 05 Python
python发送邮件实例分享
Jul 28 Python
Python中将dataframe转换为字典的实例
Apr 13 Python
python增加图像对比度的方法
Jul 12 Python
Django框架中间件定义与使用方法案例分析
Nov 28 Python
Python语法之精妙的十个知识点(装B语法)
Jan 18 Python
Python安装OpenCV的示例代码
Mar 05 Python
利用django model save方法对未更改的字段依然进行了保存
Mar 28 Python
Python Tornado核心及相关原理详解
Jun 24 Python
python爬取youtube视频的示例代码
Mar 03 Python
Django ORM判断查询结果是否为空,判断django中的orm为空实例
Jul 09 #Python
Python Selenium模块安装使用教程详解
Jul 09 #Python
OpenCV 使用imread()函数读取图片的六种正确姿势
Jul 09 #Python
django模型类中,null=True,blank=True用法说明
Jul 09 #Python
Python pip安装第三方库实现过程解析
Jul 09 #Python
详细分析Python可变对象和不可变对象
Jul 09 #Python
OpenCV4.1.0+VS2017环境配置的方法步骤
Jul 09 #Python
You might like
浅析php创建者模式
2014/11/25 PHP
php判断两个浮点数是否相等的方法
2015/03/14 PHP
Laravel6.0.4中将添加计划任务事件的方法步骤
2019/10/15 PHP
写给想学习Javascript的朋友一点学习经验小结
2010/11/23 Javascript
IE6、IE7中setAttribute不支持class/for/rowspan/colspan等属性
2011/08/28 Javascript
使用javascript实现监控视频播放并打印日志
2015/01/05 Javascript
详解jQuery移动页面开发中的ui-grid网格布局使用
2015/12/03 Javascript
常用原生js自定义函数总结
2016/11/20 Javascript
jQuery Easyui datagrid行内实现【添加】、【编辑】、【上移】、【下移】
2016/12/19 Javascript
JavaScript简介_动力节点Java学院整理
2017/06/26 Javascript
vue2.0 + ele的循环表单及验证字段方法
2018/09/18 Javascript
express如何解决ajax跨域访问session失效问题详解
2019/06/20 Javascript
vue 路由meta 设置导航隐藏与显示功能的示例代码
2020/09/04 Javascript
vue-cli —— 如何局部修改Element样式
2020/10/22 Javascript
微信小程序实现多张图片上传功能
2020/11/18 Javascript
[02:36]DOTA2上海特锦赛 回忆电竞生涯的重要瞬间
2016/03/25 DOTA
Django1.7+python 2.78+pycharm配置mysql数据库
2016/10/09 Python
python基于SMTP协议发送邮件
2019/05/31 Python
Python3 实现串口两进程同时读写
2019/06/12 Python
Python 函数list&read&seek详解
2019/08/28 Python
使用Pandas的Series方法绘制图像教程
2019/12/04 Python
关于ZeroMQ 三种模式python3实现方式
2019/12/23 Python
pytorch之Resize()函数具体使用详解
2020/02/27 Python
详解用Pytest+Allure生成漂亮的HTML图形化测试报告
2020/03/31 Python
Shopping happy life西班牙:以最优惠的价格提供最好的时尚配饰
2020/03/13 全球购物
波兰汽车配件网上商店:iParts.pl
2020/09/08 全球购物
小型女装店的创业计划书
2014/01/09 职场文书
文明礼仪小标兵事迹
2014/01/12 职场文书
特色冷饮店创业计划书
2014/01/28 职场文书
招股说明书范本
2014/05/06 职场文书
安全生产标语
2014/06/06 职场文书
官僚主义现象查摆问题整改措施
2014/10/04 职场文书
2015年国庆放假通知范文
2015/08/18 职场文书
党校团干班培训心得体会
2016/01/06 职场文书
拒绝盗图!教你怎么用python给图片加水印
2021/06/04 Python
angular4实现带搜索的下拉框
2022/03/25 Javascript