|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
记录分享第一次下视频
一.
某天发现不清楚是谁在我的浏览器中给我收藏了一个yellow网站(恼怒)! (目标网站:https://www.xian网址xian164.com/)
在我批判性研究下发现里面不只是小视频,还有一些电影和电视剧,瞌睡了来枕头,爬不了正规网站我还爬不了你嘛,于是本着柿子挑软的捏,第一次爬虫的目标就是你了!
需要准备的工具:ffmpeg、python各种库、mitmdump
二.
检查网页播放视频时的network发现是流媒体模式(机械专业的并不懂,问chatgpt说的),视频被分为若干.ts结尾的文件,其中小视频的xhr请求含参数加密(如:hls/NwL6ViJC.ts),电影电视剧并没有参数加密(如:hls/2fabd183470000008.ts)
我们先验证下按照xhr中的url能否下载视频片段,是否存在登录验证等其他阻碍下载的机制,向chat提问:编写一段python代码,按照url下载网页中的视频片段
- import urllib.request
- url = "目标url"
- filename = "video_segment.ts" # 视频片段保存的文件名
- try:
- urllib.request.urlretrieve(url, filename)
- print("视频片段已保存为", filename)
- except Exception as e:
- print("下载失败:", e)
复制代码
非常幸运直接就可以下载视频片段,所以本次行动分为两部分,含加密参数视频的爬取和不含加密参数视频的爬取
三.
1.
不含加密参数视频的爬取
例如电影《秦岭迷窟》,打开网页检查页面的network,可以发现视频片段的url请求非常规律例如:https://vip.ffzy-play7.com/20221 ... fabd183470000113.ts,结尾的2fabd183470000113部分以此增大就好,所以我们只需要做个循环,下载所有片段就好。具体代码还是由chatgpt提供,以下是验证可行的代码:
- import urllib.request
- import os
- import datetime
- # 定义下载的起始和结束索引,这里下载四个片段作为演示
- start_index = 5
- end_index = 8
- # 创建一个目录用于保存下载的片段
- segment_folder = "video_segments"
- if not os.path.exists(segment_folder):
- os.makedirs(segment_folder)
- # 创建日志文件
- log_file = open(os.path.join(segment_folder, "video_download_log.txt"), "a")
- # 创建视频片段文件列表
- segment_files = []
- # 提取固定部分的URL
- base_url = "https://vip.ffzy-play7.com/20221125/6964_b388eef9/2000k/hls/2fabd183470" #url后6位为变动部分
- # 循环下载视频片段
- for i in range(start_index, end_index + 1):
- # 构造当前片段的 URL
- url = f"{base_url}{str(i).zfill(6)}.ts"
- filename = os.path.join(segment_folder, f"{str(i).zfill(6)}.ts") # 视频片段保存的文件名
- try:
- urllib.request.urlretrieve(url, filename)
- print(f"视频片段 {filename} 已下载")
- log_file.write(f"[{datetime.datetime.now()}] 下载完成:{filename}\n")
- segment_files.append(f"{str(i).zfill(6)}.ts") # 添加片段文件名到列表,去掉前缀
- except Exception as e:
- print(f"下载失败: {url},错误信息: {e}")
- log_file.write(f"[{datetime.datetime.now()}] 下载失败:{url},错误信息:{e}\n")
- # 关闭日志文件
- log_file.close()
- # 切换工作目录到视频片段所在的文件夹
- os.chdir(segment_folder)
- # 将片段文件名写入到 video_segments.txt 文件中
- segment_list_file = "video_segments.txt"
- with open(segment_list_file, "w") as file:
- for segment_file in segment_files:
- file.write(f"file '{segment_file}'\n")
- # 使用 FFmpeg 合并视频片段
- output_video_path = "video.mp4"
- ffmpeg_command = f"ffmpeg -f concat -safe 0 -i {segment_list_file} -c copy {output_video_path}"
- ffmpeg_status = os.system(ffmpeg_command)
- print(f"FFmpeg 命令执行状态: {ffmpeg_status}")
- if ffmpeg_status == 0:
- print(f"视频合并完成,保存为 {output_video_path}")
- else:
- print("视频合并失败,请检查错误信息。")
复制代码
由此即可下载想要的电影电视剧了
展望:①可以使用chat重构代码,使用异步爬虫加快下载速度②这里下载需要输入的主要参数是目标电影的xhr的url,以后可以加入网页解析功能,输入变量改为网址或者电影名字,获取url部分由python代码完成,甚至做个ui就更方便了。
2.
含加密参数的小视频就没法通过循环来下载了(悲),以下是我想的几种下载途径:①破解加密,由代码构造加密url——能力有限,破解失败(确实难为小白了,hook都不知道hook啥)②监控xhr请求,检测到符合格式的xhr请求就记录下来下载,使用selenium自动控制网页(检测不到目标格式的请求,验证下可以收到其他格式的xhr,chat说是跨域请求,不懂,这里的代码附在评论中,请求大佬指点)③使用mitmdump,网页检测不到xhr我代理总检测得到了吧,所有符合格式的请求全部保存,然后使用ffmpeg合并视频(成功)
以下是mitmdump配合的python代码
- # mitmdump -s video.py(启用mitmdump)
- import os
- from mitmproxy import ctx
- OUTPUT_FOLDER = 'mitm_video_segments'
- os.path.exists(OUTPUT_FOLDER) or os.makedirs(OUTPUT_FOLDER)
- def response(flow):
- url = 'https://vip.ffzy-play7.com/20221125/6964_b388eef9/2000k/hls/' # 替换为你要拦截的视频片段的URL前缀
- if flow.request.url.startswith(url):
- content = flow.response.content
- if not content:
- return
- # 获取已保存的视频片段文件数,用于命名新文件
- num_files = len(os.listdir(OUTPUT_FOLDER))
- # 生成文件名
- filename = f'{OUTPUT_FOLDER}/{num_files + 1:04d}.ts' # 使用四位数格式,例如0001.ts, 0002.ts
- # 写入文件
- with open(filename, 'wb') as f:
- f.write(content)
复制代码
下载之后使用ffmpeg合并视频,附代码
- import os
- # 视频片段所在文件夹路径
- video_folder = '输入路径/mitm_video_segments'
- # 输出视频文件名
- output_video = 'output_video.mp4'
- # 构建 ffmpeg 命令
- ffmpeg_command = f'ffmpeg -i "concat:'
- # 遍历视频片段文件夹,构建视频片段列表
- video_files = [f for f in os.listdir(video_folder) if f.endswith('.ts')]
- for video_file in sorted(video_files):
- ffmpeg_command += f'{video_folder}/{video_file}|'
- ffmpeg_command = ffmpeg_command[:-1] + f'" -c copy "{output_video}"'
- # 执行 ffmpeg 命令
- os.system(ffmpeg_command)
- print(f'合并完成,输出文件为 {output_video}')
复制代码
展望:可添加时间控制部分,一段时间没有收到url即为下载完成 |
评分
-
查看全部评分
|