赞
踩
仅做技术分享使用,如侵必删
以某网站的视频为例(不同网站的规则不同,这是其中一种未加密的)
F12进入开发者模式,在Network中找到mp4文件(可以从Media中筛选)
Request URL对应的就是视频下载地址,也可以用下载器直接下载
必须要有完整的请求头信息,否则要么无法访问URL,要么视频无法正确解码
像这个是不可用的。
此时可以尝试将下载链接复制到浏览器地址栏去重新打开
便可获得完整的请求头信息
附上自用的工具类源码,可将复制粘贴的请求头信息保存为字典类型
# -*- coding = utf-8 -*- # @Time : 2021/5/11 16:50 # @Author : xyx-Eshang # @File : headersUtil.py # @software : PyCharm import re # 根据文本内容,获得headers def getHeaders(headersStr): headers = {} headersList = re.findall(r':?(.*?): (.*)\n?', headersStr) for headersTuple in headersList: headers[headersTuple[0]] = headersTuple[1] return headers
文件名在下载链接中可以看到,这里使用正则表达式将文件名从url中提取出来
保存路径对应的目录必须被提前创建好
如果路径不存在,直接用open()去调用是会报错的。
强调下面两个函数:
import os
os.mkdir("路径") # 创建文件夹
os.makedirs("路径") # 创建包括父级文件夹在内的各级文件夹
1) os.mkdir()按照参数去创建文件夹,但如果中间某一父级文件夹不存在,就会报错。以下方为例
os.mkdir("../abc/def") # 根据相对路径"../abc/def"创建def文件夹
如果…/abc这个文件夹存在,那么程序就可以正常执行;
但如果…/abc文件夹不存在,此时程序就会报错
2) os.makedirs()按照参数去逐级创建文件夹,能有效避免上述可能出现的错误,如果某一父级文件夹不存在,会一并创建。
一切准备就绪以后,开始编写download()函数,需要的参数分别是
1) url
2) headers:请求头信息
3) full_file_name:完整的文件名
4) download_path:文件保存路径
open()的模式必须用bytes模式,
覆盖写入用"wb",追加写入(视频拼接)用"ab"
附源代码
def download(url, headers, full_file_name, download_path): request = urllib.request.Request(url=url, method="GET", headers=headers) print("正在下载:" + full_file_name, end="...") try: response = urllib.request.urlopen(request) # 更换操作路径 os.chdir(download_path) # 将下载的文件从内存拷贝到本地磁盘 file = open(full_file_name, "wb") file.write(response.read()) file.close() print("下载完成!") except urllib.error.HTTPError as e: if e.code == 404: print("该文件不存在!") else: print(e)
有的网站上传的视频是经过m3u8加密处理过的
这类视频的特点是:
完整的视频会被切割成很多个扩展名为.ts的小片段
如下图所示,F12进入开发者工具,在XHR中筛选
由之前的内容可以得知,Request URL的内容就是这个视频片段的下载地址
而下载地址又和命名有关,仔细观察不难发现,文件的命名规则都是:
xxxxxxxx000.ts
xxxxxxxx001.ts
xxxxxxxx002.ts
有这样的规律就好办了,遍历下载所有的ts文件即可
这里针对核心部分,书写大致思路
观察得知,一个视频的所有ts文件,url前面部分都是一样的
唯一的区别是后面的数字000、001、002…(或是00、01、02…)
因此可以用While True循环获取:
1) urlList:保存了所有的url
2) fullFileNameList:保存了所有的文件名(包括扩展名)
# 比如一共有3个ts文件,url分别是 # https://abcdefg01.ts # https://abcdefg02.ts # https://abcdefg03.ts urlList = [] # 保存所有的url fullFileNameList = [] # 保存所有的完整文件名 count = 0 # 计数器 baseUrl = "https://abcdefg" # url前面完全一致的部分 while True: try: # 处理fullFileName # 由于数字是01、02、03,这里需要手动拼接 if(count < 10): fullFileName == "0" + str(count) + ".ts" else: fullFileName == str(count) + ".ts" # 保存到列表中 fullFileNameList.append(fullFileName) # 处理url url = baseUrl + fullFileName # 保存到列表中 urlList.append(url) except urllib.error.HTTPError as e: # 报404时,说明已经遍历完毕,终止循环 if e.code == 404: break else: print(e)
循环访问urlList的元素即可
保存的文件名则是fullFileNameList的元素
整体和上面思路几乎一直,只是在外层嵌套了循环
详细说明将耗费大量篇幅,因此这里留给大家独立完成
在下载好所有的ts文件以后,便可以将这些文件合并起来
特别注意
在前面命名的时候,一定要把前面的"0"给加上,否则视频将不会按照期望的顺序去执行合并!
copy /b 原视频路径.* 新视频路径\合并文件名
比如这里希望将D:\Python下的所有ts文件,合并成combinedFile.mp4
那么指令就是
copy /b D:\Python.* D:\Python\combinedFile.mp4
附源代码
def combineFiles(combinedFileName, downloadPath): # 更换操作目录 os.chdir(downloadPath) try: # 若原有文件,则先移除文件 os.remove(combinedFileName) except FileNotFoundError: # 若原来没有该文件,不做任何操作 pass # 获取所有文件名 allTsFileNames = os.listdir() for tsFileName in allTsFileNames: tsFile = open(tsFileName, "rb") combinedFile = open(combinedFileName, "ab") # 向目标文件追加内容 combinedFile.write(tsFile.read()) tsFile.close() # 删除ts文件 os.remove(tsFileName) print("合并完成") os.chdir(defaultPath)
其中defaultPath是文件的默认操作路径,已在外层定义好
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。