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计算三角函数之asin()方法的使用
May 15 Python
python中星号变量的几种特殊用法
Sep 07 Python
Python中模块pymysql查询结果后如何获取字段列表
Jun 05 Python
Python标准库sched模块使用指南
Jul 06 Python
神经网络python源码分享
Dec 15 Python
Python实现学生成绩管理系统
Apr 05 Python
python实现将excel文件转化成CSV格式
Mar 22 Python
Python实现制度转换(货币,温度,长度)
Jul 14 Python
pyenv与virtualenv安装实现python多版本多项目管理
Aug 17 Python
Python连接SQLite数据库并进行增册改查操作方法详解
Feb 18 Python
python图片合成的示例
Nov 09 Python
Python中的 Set 与 dict
Mar 13 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实现的生成静态HTML速度快类库
2007/03/31 PHP
实用函数7
2007/11/08 PHP
ThinkPHP的I方法使用详解
2014/06/18 PHP
php购物车实现方法
2015/01/03 PHP
使用ltrace工具跟踪PHP库函数调用的方法
2016/04/25 PHP
php及codeigniter使用session-cookie的方法(详解)
2017/04/06 PHP
Laravel6.2中用于用户登录的新密码确认流程详解
2019/10/16 PHP
用函数模板,写一个简单高效的 JSON 查询器的方法介绍
2013/04/17 Javascript
jquery实现tr元素的上下移动示例代码
2013/12/20 Javascript
Firefox下无法正常显示年份的解决方法
2014/09/04 Javascript
asp知识整理笔记3(问答模式)
2015/09/27 Javascript
利用JS生成博文目录及CSS定制博客
2016/02/10 Javascript
js只执行1次的函数示例
2016/07/20 Javascript
layui添加动态菜单与选项卡
2019/07/26 Javascript
微信小程序动态设置图片大小的方法
2019/11/21 Javascript
JS实现多选框的操作
2020/06/24 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
2020/09/28 Javascript
[02:34]肉山说——泡妞篇
2014/09/16 DOTA
[01:17]辉夜杯战队访谈宣传片—EHOME
2015/12/25 DOTA
Python里隐藏的“禅”
2014/06/16 Python
在Python中使用next()方法操作文件的教程
2015/05/24 Python
python处理csv中的空值方法
2018/06/22 Python
Python3.7.0 Shell添加清屏快捷键的实现示例
2020/03/23 Python
scrapy利用selenium爬取豆瓣阅读的全步骤
2020/09/20 Python
使用HTML5 Canvas API控制字体的显示与渲染的方法
2016/03/24 HTML / CSS
波兰运动鞋网上商店:e-Sporting
2018/02/16 全球购物
Burt’s Bees英国官网:世界领先的天然个人护理品牌
2020/08/17 全球购物
请解释一下webService? 如何用.net实现webService
2014/06/09 面试题
工程师自我评价怎么写
2013/09/19 职场文书
财务会计毕业生自荐信
2013/11/02 职场文书
2014信息公开实施方案
2014/02/22 职场文书
实习生评语
2014/04/26 职场文书
教师纪念9.18事件演讲稿范文
2014/09/14 职场文书
乡镇党的群众路线教育实践活动总结报告
2014/10/30 职场文书
参观邀请函范文
2015/02/02 职场文书
详解Python为什么不用设计模式
2021/06/24 Python