利用python下载钉钉群直播视频

今年因为疫情的原因不能开学,所以很多学校都使用钉钉进行在线授课,但是在钉钉里面点击下载群直播回放的时候却发现:
Snipaste_2020-04-25_09-04-10.png
Snipaste_2020-04-25_09-04-10.png

真好,管理员设置了不允许下载回放。这就完了吗?NoNoNo!既然正常途径下载不了,那么我们就通过程序来进行下载。

环境准备

fiddler抓包软件,钉钉PC客户端,格式工厂软件,python环境以及requests,moviepy库。
新建一个python文件dingding.py,在python文件所在位置新建一个‘钉钉’文件夹来存放数据。
桌面新建一个文件夹,名称默认‘新建文件夹’就好,然后在新建文件夹里面新建一个‘video’文件夹以及video_add.py文件。

抓取思路

我们在网站观看视频的时候,并不是一次性的将所有视频内容全部请求完,而是把它分为了很多小段视频,每次请求一小段。这一规则,几乎所有的视频网站以及视频软件都是如此,所以这就导致了我们在爬取视频的时候,并不能一次性爬取到视频的全部,而爬取下来的视频是一小节一小节的分开的ts文件;所以我们在抓取视频的时候,首先得获取到每一个小节视频的URL地址,然后去请求它,将所有小节的ts文件保存下来,然后再使用格式工厂将所有ts文件转换成MP4格式,最后再将所有的MP4文件合并为一个MP4文件。那么按照这个思路,我们开始实际的操作。

抓取分析

首先我们需要先获取到每个小节视频的URL地址,由于不是在浏览器当中,所以我们会用到fiddler来对软件的数据包进行抓取;打开fiddler抓包软件,然后登陆钉钉PC客户端,找到你想要下载的群直播回放视频:

Snipaste_2020-04-24_23-15-39.png
Snipaste_2020-04-24_23-15-39.png
然后打开第一个视频并播放,我们就可以在fiddler软件当中看到抓取到的数据包:
批注 2020-04-24 231935.jpg
批注 2020-04-24 231935.jpg
在图中我标记的1号数据包下面的那个数据包,就是当前视频所有小节的URL地址;大家可以选中这条数据,然后在右边Inspectors中的Raw当中打开GET后面的链接,会提示你下载一个文件,将这个文件下载到本地,然后使用记事本打开,就可以看到当前视频每一个小节的URL地址(图中红色边框选中,并且所有类似选框内的皆是):
Snipaste_2020-04-24_23-45-06.jpg
Snipaste_2020-04-24_23-45-06.jpg
当然,这些URL地址是不完整的,因为他们前面省略了“https://dtliving-pre.alicdn.com/live/”这些;如何得知呢?点击刚才标记1号数据包下面紧挨着的2号视频数据包,然后注意观察他们在右边Inspectors中的Raw当中打开GET后面的链接,刚好省略了前面的一部分内容。当然你也可以多找几组作以对比。

代码书写

接下来,我们就可以进行到代码书写的环节:打开我们创建的dingding.py文件,导入requests库,然后将我们刚才获取到的1号数据包里面的下载URL地址写入,再写入请求头,由于我们暂时不知道它需要哪些请求头的参数,所以我们索性将fiddler上所有的请求头参数都写上,然后我们先打印一下状态码,看是否可以请求成功:

import requests

def dingding():
    url='https://dtliving-pre.alicdn.com/live/bd82384b-883e-444b-8499-2b60bfc244e0_merge.m3u8?app_type=win&auth_key=1590309873-0-0-745e015e4c7a1580895c875450c97d7c&cid=5977ad6e9da132f335b2d62203b7beed&token=bd58052a744b52e78d01bc9328bbf2f52n6pZZhOITKrfmA40UASVqOs0tbqts1jxM7u0Hoef9hPqAHJMoaeWYXB01SjavnoT5Ke3pM1VC3IKxt9b1MxXh540meiaUNU-m_nzJFKHN4=&token2=3b5453fbca3841e11d534ac7ecc7d9a5fNFEc-4e5ZTb8k6SKy22dqh7fq5krVqHURw0pJx8hU6YOhtP5aKSXdHODZCvmwFdMSxtREtJJF03LntnCpvzvSx_g4OBfmcSnSDin-Peyk4&version=5.0.15-Release.26'
    headers={
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 dingtalk-win/1.0.0 nw(0.14.7) DingTalk(5.0.15-Release.26) Mojo/1.0.0 Native AppType(release)',
        'Accept-Language':'zh-CN,zh;q=0.9',
        'Accept-Encoding':'gzip, deflate, br',
        'Accept':'*/*',
        'Referer':'https://h5.m.taobao.com/tblive/dingtalk/pc-playback.html?cid=31664625310&uuid=bd82384b-883e-444b-8499-2b60bfc244e0&anchorId=275440629',
        'Origin':'https://h5.m.taobao.com',
        'Connection':'keep-alive',
        'Host':'dtliving-pre.alicdn.com'
    }
    response=requests.get(url,headers=headers)
    print(response)
if __name__ == '__main__':
    dingding()

运行程序之后,我们会看到一个SSL的报错,这是因为我们请求的是HTTPS请求,所以会出现这种情况,解决它,我们一般只需要在requests.get的参数里面加上“verify=False”即可,意思就是不验证SSL证书;这时我们再运行程序,就发现我们的报错没有了,而是多了一个Warning警告,这个警告我们可以不用理它,因为它并不会使我们的程序无法运行,或者也可以使用下面的代码忽略warning:

import warnings

warnings.filterwarnings('ignore')

再运行程序,我们就看不到刚才的Warning警告了。接下来,我们的思路就是请求这个URL地址,然后将该地址里面的文件保存成txt文件存放在本地,然后再读取这个txt文件里面的内容,利用正则表达式将我们所需要的每小节视频的URL地址提取出来,再将缺少的部分拼接上,然后请求即可。有了这个思路,我们的代码书写起来就很容易了;下面是完整代码展示:

import requests
import re
import warnings

# 忽略警告
warnings.filterwarnings('ignore')

i=1
def dingding():
    url = 'https://dtliving-pre.alicdn.com/live/bd82384b-883e-444b-8499-2b60bfc244e0_merge.m3u8?app_type=win&auth_key=1590309873-0-0-745e015e4c7a1580895c875450c97d7c&cid=5977ad6e9da132f335b2d62203b7beed&token=bd58052a744b52e78d01bc9328bbf2f52n6pZZhOITKrfmA40UASVqOs0tbqts1jxM7u0Hoef9hPqAHJMoaeWYXB01SjavnoT5Ke3pM1VC3IKxt9b1MxXh540meiaUNU-m_nzJFKHN4=&token2=3b5453fbca3841e11d534ac7ecc7d9a5fNFEc-4e5ZTb8k6SKy22dqh7fq5krVqHURw0pJx8hU6YOhtP5aKSXdHODZCvmwFdMSxtREtJJF03LntnCpvzvSx_g4OBfmcSnSDin-Peyk4&version=5.0.15-Release.26'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 dingtalk-win/1.0.0 nw(0.14.7) DingTalk(5.0.15-Release.26) Mojo/1.0.0 Native AppType(release)',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept': '*/*',
        'Referer': 'https://h5.m.taobao.com/tblive/dingtalk/pc-playback.html?cid=31664625310&uuid=bd82384b-883e-444b-8499-2b60bfc244e0&anchorId=275440629',
        'Origin': 'https://h5.m.taobao.com',
        'Connection': 'keep-alive',
        'Host': 'dtliving-pre.alicdn.com'
    }
    # 获取二进制数据
    response = requests.get(url, headers=headers, verify=False).content

    # 将.content二进制转换为str数据类型,否则会报数据类型错误
    wenjian = response.decode('utf-8')

    # 保存txt文件
    with open('钉钉/1.txt', 'w')as f:
        f.write(wenjian)

    # 读取txt文件
    with open('钉钉/1.txt', 'r')as f:
        wenben = f.read()

        # 使用正则表达式进行数据匹配
        url1 = re.findall(r'.*?-.*?-.*?-\d+-.*?/\d+\.ts\?auth_key=\d+-0-0-.*', wenben)

        global i
        for url_video in url1:
            # 将匹配到的数据拼接完整
            url_video_all = 'https://dtliving-pre.alicdn.com/live/' + url_video

            # 请求所有小节视频的URL链接
            video_response = requests.get(url_video_all, headers=headers, verify=False).content

            # 将所有小节的ts文件存放到新建的‘钉钉’文件夹
            with open('钉钉/{}.ts'.format(i), 'wb')as f:
                f.write(video_response)
            i += 1

            # 显示正在保存的内容
            print('正在保存{}.ts'.format(i))


if __name__ == '__main__':
    dingding()

视频整合

然后我们在钉钉文件夹当中就可以看到我们保存的所有ts文件:
Snipaste_2020-04-25_00-26-17.png
Snipaste_2020-04-25_00-26-17.png

然后我们使用格式工厂软件,将所有的文件转换为MP4格式:
Snipaste_2020-04-25_13-26-19.png
Snipaste_2020-04-25_13-26-19.png
点击添加文件夹,将存储所有ts文件的文件夹添加进来,然后转换成MP4格式,存放在指定文件夹(在输出文件夹指定)。这里我们将输出文件放在桌面新建文件夹中的video。视频整合我们所用到的库叫做moviepy,这个库可以对视频进行整合、裁剪以及一些剪辑操作,我们目前只会使用合并视频的功能,所以对其他功能不做介绍。打开之前创建的video_add.py文件,写入下列代码:
from natsort import natsorted
from moviepy.editor import *
import os

# 定义一个空列表存放数据
L=[]

# 将video文件夹中的视频导入
for root,dirs,files in os.walk('./video'):
    # 按照1,2,3,4……的顺序排列视频
    files = natsorted(files)
    # files.sort()

    for file in files:
        # 进行if判断,如果文件后缀名是MP4,那么就将其添加至列表
        if os.path.splitext(file)[1]=='.mp4':
            filePath=os.path.join(root,file)
            video=VideoFileClip(filePath)
            L.append(video)

# 将列表视频合并
final_clip=concatenate_videoclips(L)
# 将合并好的视频输出为target.mp4文件,帧率24
final_clip.to_videofile('./target.mp4',fps=24)

等待程序运行完成,就可以在新建文件夹当中就可以看到已经合并好的视频target.mp4文件。
这样就完成了对群直播回放视频的保存工作。
原创不易,未经作者授权,禁止转载,谢谢合作!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容