下载微信公众号的视频
作为一个专业的程序媛,前端时间折腾龙虾转发公众号的文章到闺蜜圈wiki,之前已经处理了图片和文章的问题,今天转发的时候发现另外一个问题:文章里面的视频无法正常播放。
刚开始的时候想着直接去chrome的缓存里面找,但是试了下chrome://cache发现无效,又不想去找插件来干这件事情。直接去调试工具找对应的视频地址:
然而直接贴到地址栏,直接报403了。
唉,好尴尬,既然有本地缓存文件了。那么直接尝试将接收到的数据流写入到文件呗。找了半天没发现怎么直接把请求到的数据写入到文件,点击开始播放等待缓冲结束。
加载完了右下角的数据也就有了,直接切换成base64,复制粘贴:
然而,尝试decode 之后,播放不了,缺少mp4的头文件,这就挺奇怪的。文件头哪里去了?my_video为通过代码下载的mp4,video为通过base64 处理的图片。
文章测试地址:https://mp.weixin.qq.com/s/heoer_zm4SFwFKsk4tRecQ
看了下是video标签实现的:
<div data-v-c66e8e28="" class="js_inner inner not_fullscreen"><div data-v-c66e8e28="" class="js_video_poster video_poster"><div data-v-c66e8e28="" class="video_mask"></div><video data-v-c66e8e28="" src="https://mpvideo.qpic.cn/0bc3pidsgaahauamxiglsruvo6wden5aoiya.f10002.mp4?dis_k=247900efb8791f0718998ea0813793c9&dis_t=1775118363&play_scene=10120&auth_info=d9/5u/dlYUBWn6qY0Sp2SXM9PUdEOj5CZmQ3H2k2TzNOXXtjTwYQen0+WTMXEzdWIDNuS0hkIHgTMSlENWAcfUpBcQ==&auth_key=ed4a91866522f27b4b89c5e71e04d115&vid=wxv_4453415887525888005&format_id=10002&support_redirect=0&mmversion=false" poster="http://mmbiz.qpic.cn/sz_mmbiz_jpg/GAVxEAgJstytcf0uF3dpdZKia9G96C3loxCNaBrbFLHCiak3GvJDfASC7uYqNjjAZ5e2OHSmHoBQrONRJ8UIq6icJjjFXMfUBtdhy7VWlfb3MM/0?wx_fmt=jpeg&wxfrom=16" webkit-playsinline="isiPhoneShowPlaysinline" playsinline="isiPhoneShowPlaysinline" preload="metadata" crossorigin="anonymous" controlslist="nodownload" class="" style="display: block; width: 655px; height: 492px;"> 您的浏览器不支持 video 标签 </video></div><div data-v-f4ee5450="" data-v-c66e8e28="" class="video_poster__info__play" style="display: none;"><i data-v-f4ee5450="" data-v-c66e8e28="" class=""></i></div><div data-v-f4ee5450="" data-v-c66e8e28="" class="video_poster__info" style="display: none;"><p data-v-f4ee5450="" data-v-c66e8e28="" class="video_poster__info__title" style="font-size: 17px;">继续观看</p><p data-v-f4ee5450="" data-v-c66e8e28="" class="video_poster__info__desc" style="font-size: 12px;"> 孤独症,就是不爱说话吗? </p></div><div data-v-f4ee5450="" data-v-c66e8e28="" class="video_poster__info__mask" style="width: 100%; display: none;"></div></div>
还是说着这个东西还有另外的处理逻辑?哪位大神知道原因还望不吝赐教。
既然decode不行,那就直接上代码吧:
#!/usr/bin/env python3
"""
下载 mpvideo.qpic.cn 等需 Referer 的 MP4(微信视频 CDN)。
Author: obaby
https://zhongxiaojie.cn
https://oba.by
"""
import argparse
import sys
import urllib.error
import urllib.request
# 与常见微信内嵌页一致,避免 403
DEFAULT_REFERER = "https://mp.weixin.qq.com/"
DEFAULT_UA = (
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 "
"MicroMessenger/7.0.20"
)
def main() -> None:
p = argparse.ArgumentParser(description="带 Referer 下载 mpvideo MP4")
p.add_argument("url", help="完整 mp4 URL(含查询参数)")
p.add_argument(
"-o",
"--output",
default="downloaded.mp4",
help="保存路径(默认 downloaded.mp4)",
)
p.add_argument("--referer", default=DEFAULT_REFERER, help="Referer 头")
p.add_argument("--user-agent", default=DEFAULT_UA, help="User-Agent")
args = p.parse_args()
req = urllib.request.Request(
args.url,
headers={
"User-Agent": args.user_agent,
"Referer": args.referer,
},
method="GET",
)
try:
with urllib.request.urlopen(req, timeout=120) as resp:
data = resp.read()
except urllib.error.HTTPError as e:
print(f"HTTP {e.code}: {e.reason}", file=sys.stderr)
sys.exit(1)
out = open(args.output, "wb") if args.output != "-" else sys.stdout.buffer
try:
out.write(data)
finally:
if out is not sys.stdout.buffer:
out.close()
print(f"已写入 {args.output},{len(data)} 字节")
if len(data) >= 8 and data[4:8] == b"ftyp":
print("魔数检测:疑似标准 MP4(含 ftyp)")
if __name__ == "__main__":
main()
现在就可以下载之后,上传了,发布的文章地址: