【Rust 实战】抖音短视频解析工具

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【Rust 实战】抖音短视频解析工具

0x00 开篇


一直都在写教程,今天咱们换换主题,一起来做一个小工具。咱们用 Rust 来写一个抖音短视频下载地址解析工具。本文用到异步、网络请求等相关知识。另外公众号官方社群(文末)也开放了,欢迎大家加入,一起畅谈 Rust 的未来。本篇文章的阅读时间大约 8 分钟。


0x01 视频解析原理


原理其实很简单,每个短视频对应一个 id,我们将 id 传给官方的 api 地址:https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={id} 以得到当前短视频一些信息,如:视频名称,封面图片,音频地址,视频地址等等。这其中的视频地址就是可以下载的地址了。

id = 7162104318923967752 为例,请求的信息如下:


0a2653c851af460fa595bd959398a8f1.png


最终 video/url_list 中的值就是我们想要的了。


0x02 代码实现


添加第三方 crate 依赖


本篇文章将使用下面的依赖:

  • 异步:tokio
  • 网络请求:reqwest
  • json 解析: serde
# 异步
tokio = { version = "1.21.2", features = ["full"] }
# 网络
reqwest = {version = "0.11.12", features = ["json"] }
# json
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }


获取短视频 id


首先,我们通过用户输入的地址,获取短视频 id。短视频的地址都是如 https://v.douyin.com/xxxxxxx这种形式。当我们在浏览器请求此链接时,将会重定向为一个新的地址,我们所需的 id 就在新的地址中。

请求接下来以 https://v.douyin.com/h1YcUow 为例

直接上代码了:

let mut input = String::new();
// 输入 https://v.douyin.com/h1YcUow
std::io::stdin().read_line(&mut input).expect("read line error!");
// 获取 response
let result = create_default_client().get(input.as_str()).send().await;
let result = result.unwrap();
dbg(&result);
// 获取重定向后的地址,并解析id
let path = result.url().path();
let id = path.replace("/video/", "");

用户先输入短视频分享的链接https://v.douyin.com/h1YcUow, 然后请求这个链接,通过返回结果 response 中的 path 获取 id。下面是 response 的结果。

&result = Response {
    url: Url {
        scheme: "https",
        cannot_be_a_base: false,
        username: "",
        password: None,
        host: Some(
            Domain(
                "www.douyin.com",
            ),
        ),
        port: None,
  // 7162104318923967752 就是我们所需的 id
        path: "/video/7162104318923967752",
        query: Some(
            "previous_page=web_code_link",
        ),
        fragment: None,
    },
.....
}


通过 id 拼接链接并请求


// 请求拼接请求地址
let url = "https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=";
let url = format!("{}{}", url, id);
// 请求该链接
let result = create_default_client().get(url.as_str()).send().await;
// 结果转化为结构体
let result = result.unwrap().json::<DouYinResult>().await;

id 与链接拼接并请求,将请求结果通过 serde 转为 Rust 相对应的结构体。(DouYinResult 请参见源码)。


解析结果


let dou_yin_items = result.item_list.unwrap();
let dou_yin_item = dou_yin_items.into_iter().nth(0).unwrap();
// 视频名称
let video_name = dou_yin_item.desc.unwrap_or_default();
// 视频地址
let dou_yin_video = dou_yin_item.video.unwrap();
// 获取 play_address
let play_address = dou_yin_video.play_addr.unwrap();
// 获取 play_list
let play_list = play_address.url_list.unwrap_or_default();
// video url
let video_url = play_list.into_iter().nth(0).unwrap_or_default();

由于篇幅有限,上面解析的代码使用了大量 unwrap(),详细代码请参阅源码,项目中不建议大量使用 unwrap()。我们最终拿到的地址如下:

https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200fg10000cdieeejc77ucgndnburg&ratio=720p&line=0

这个地址就可以下载了。但是有个缺点,这个地址有水印,如果想要去掉水印,我们把地址中的 playwm 替换为 play就可以了。

最终地址:

https://aweme.snssdk.com/aweme/v1/play/?video_id=v0200fg10000cdieeejc77ucgndnburg&ratio=720p&line=0

获取最终视频源地址

其实到上面一步已经可以正常下载了,如果我们将上面的地址再请一次,链接会重定向到最终的视频地址,代码详见源码:

https://v5-colda.douyinvod.com/e7c51c7e6ee10322808d96a89931383a/638b1b04/video/tos/cn/tos-cn-ve-15c001-alinc2/38ba1730579642d1a2a1c70822caa4e6/?a=1128&ch=0&cr=0&dr=0&cd=0%7C0%7C0%7C0&cv=1&br=1676&bt=1676&cs=0&ds=3&ft=BajzJVVywhiRF_80mo~MWwQlQmpF2O_CvrKzCHsUdo0gl-A&mime_type=video_mp4&qs=0&rc=MzwzOjM7aWg0ZGZlZWVpNUBpanhxcWY6ZmhoZzMzNGkzM0AzYWFiYTUzXzExNl9fLTYuYSNvX2FkcjRnYmZgLS1kLS9zcw%3D%3D&l=202212031645330102091481403F60B65C&btag=a8000

这个地址可以在任意浏览器或者下载工具中下载了。


0x03 小结


原理和代码都还算比较容易,用到的接口也是官方接口,失效的几率很低,大概率可以长期使用。通过测试我也发现并不是所有的视频都可以下载,极少数视频无法下载。大家如果感兴趣可以下载源码并完善。但是是不是如果有GUI界面就好了,文章还没有结束,接下来我将会结合 tauri 来完成一个跨平台的短视频解析工具。

相关文章
|
16天前
|
自然语言处理 编译器 Linux
|
16天前
|
安全 程序员 API
|
10天前
|
自然语言处理 并行计算 数据可视化
免费开源法律文档比对工具:技术解析与应用
这款免费开源的法律文档比对工具,利用先进的文本分析和自然语言处理技术,实现高效、精准的文档比对。核心功能包括文本差异检测、多格式支持、语义分析、批量处理及用户友好的可视化界面,广泛适用于法律行业的各类场景。
|
21天前
|
Prometheus 监控 Cloud Native
实战经验:成功的DevOps实施案例解析
实战经验:成功的DevOps实施案例解析
36 6
|
16天前
|
Rust 安全 Java
编程语言新宠:Rust语言的特性、优势与实战入门
【10月更文挑战第27天】Rust语言以其独特的特性和优势在编程领域迅速崛起。本文介绍Rust的核心特性,如所有权系统和强大的并发处理能力,以及其性能和安全性优势。通过实战示例,如“Hello, World!”和线程编程,帮助读者快速入门Rust。
34 1
|
17天前
|
Rust 安全 编译器
编程语言新宠:Rust语言的特性、优势与实战入门
【10月更文挑战第26天】Rust语言诞生于2006年,由Mozilla公司的Graydon Hoare发起。作为一门系统编程语言,Rust专注于安全和高性能。通过所有权系统和生命周期管理,Rust在编译期就能消除内存泄漏等问题,适用于操作系统、嵌入式系统等高可靠性场景。
29 2
|
18天前
|
UED
<大厂实战经验> Flutter&鸿蒙next 中使用 initState 和 mounted 处理异步请求的详细解析
在 Flutter 开发中,处理异步请求是常见需求。本文详细介绍了如何在 `initState` 中触发异步请求,并使用 `mounted` 属性确保在适当时机更新 UI。通过示例代码,展示了如何安全地进行异步操作和处理异常,避免在组件卸载后更新 UI 的问题。希望本文能帮助你更好地理解和应用 Flutter 中的异步处理。
61 3
|
18天前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
99 1
|
11天前
|
前端开发 中间件 PHP
PHP框架深度解析:Laravel的魔力与实战应用####
【10月更文挑战第31天】 本文作为一篇技术深度好文,旨在揭开PHP领域璀璨明星——Laravel框架的神秘面纱。不同于常规摘要的概括性介绍,本文将直接以一段引人入胜的技术剖析开场,随后通过具体代码示例和实战案例,逐步引导读者领略Laravel在简化开发流程、提升代码质量及促进团队协作方面的卓越能力。无论你是PHP初学者渴望深入了解现代开发范式,还是经验丰富的开发者寻求优化项目架构的灵感,本文都将为你提供宝贵的见解与实践指导。 ####
|
14天前
|
前端开发 JavaScript
JavaScript新纪元:ES6+特性深度解析与实战应用
【10月更文挑战第29天】本文深入解析ES6+的核心特性,包括箭头函数、模板字符串、解构赋值、Promise、模块化和类等,结合实战应用,展示如何利用这些新特性编写更加高效和优雅的代码。
32 0

推荐镜像

更多