抖音无水印解析源码分享及原理浅谈

文章摘要
该文章介绍了一个无需 cookie、原生 PHP 编写的抖音无水印解析脚本源码。作者提到抖音频繁更改网页端算法并增加人机验证,导致抓取困难,因此转向移动端解析。该脚本通过 POST 请求接收抖音分享链接,并输出包含用户昵称、视频地址、封面及图集链接等的 JSON 数据。作者已在测试环境中部署该接口,并提供链接供使用,但声明该接口仅供测试,后期不再支持稳定版。文章欢迎其他开发者提出改进方案进行交流。
— 文章部分摘要由DeepSeek深度思考而成

抖音解析做了很久了,近段时间,抖音官方经常改算法。。。

最初是抓取的抖音网页端数据,只是这欠 R 的抖音在网页端搞了人机验证,抓不到数据了。

后面又尝试抓取抖音网页的请求元数据,找到了那个包含元数据的 JS 文件,只是有一个请求所需的参数没找到。无奈放弃,有空再研究。。。

那就只能抓移动端了,虽然包含的内容少,清晰度也没网页的高,但是好在还能用(没准哪天也来个验证啥的),那就凑合用吧。

源码特点:无需 cookie,原生 php 支持,无需安装任何 php 扩展(包括 cURL)

请求方式为:POST(个人喜欢用 POST,至于为什么,经常做小程序 API 开发的应该都懂)

请求参数为:[url : 抖音分享链接]

输出格式为:JSON

完整源码如下:(源码已做注释,请自行理解源码思路,我懒得写)

<?php
/*
名称:抖音无水印解析脚本
源码作者:赵彤刚
测试环境:PHP 8.4
源码版本:v2.7.0
开源协议:Apache 2.0
最后更新:2025年1月6日
*/

// 拦截非POST请求
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
    header('Location: https://blog.heheda.top');
    exit;
}
// 响应头
header("Content-type: application/json; charset=utf-8");
header("Access-Control-Allow-Origin: *");
header("X-Powered-By: PHP/" . PHP_VERSION);
header("Content-language: zh");
// 伪造请求头
$uavalue = "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Mobile Safari/537.36";
$headers = [
    "Content-Type: application/x-www-form-urlencoded",
    "User-Agent: " . $uavalue,
    "Accept-language: zh-CN,zh;q=0.9,de;q=0.8,ug;q=0.7",
    "Referer: https://www.douyin.com/?is_from_mobile_home=1&recommend=1"
];
// 获取POST输入
$url = urldecode($_POST['url']);
// 判断是否为数字
if (is_numeric($url)) {
    $video_id = $url;
} else {
    preg_match('/https?:\/\/[^\s]+/', $url, $video_url);
    $video_url = $video_url[0];
    $redirected_url = get_redirected_url($video_url);
    preg_match('/(\d+)/', $redirected_url, $matches);
    $video_id = $matches[1];
}
// 获取数据
$adder = "https://www.iesdouyin.com/share/video/" . $video_id . "/";
$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'header' => $headers,
    ]
]);
$response = file_get_contents($adder, false, $context);
preg_match('/_ROUTER_DATA\s*=\s*(\{.*?\});/', $response, $matches);
$data = $matches[1];
// 解析JSON数据
$jsonData = json_decode($data, true);
// 筛选信息
$itemList = $jsonData['loaderData']['video_(id)/page']['videoInfoRes']['item_list'][0];
$nickname = $itemList['author'];
$video = $itemList['video']['play_addr']['uri'];
$images = $itemList['images'] ?? null;
// 构造输出
$outData = [
    'code' => empty($nickname) ? 0 : 1,
    'msg' => empty($nickname) ? '解析失败!' : '解析成功!️',
    'name' => $nickname['nickname'],
    'title' => $itemList['desc'],
    'aweme_id' => $itemList['aweme_id'],
    'video' => $video !== null ? (strpos($video, 'mp3') === false ? 'https://www.douyin.com/aweme/v1/play/?video_id=' . $video : $video) : null,
    'cover' => $itemList['video']['cover']['url_list'][0],
    'images' => array_map(function ($image) {
        return $image['url_list'];
    }, is_array($images) ? $images : []),
    'type' => empty($images) ? '视频' : '图集'
];
// 输出
echo json_encode($outData);
// 重定向方法
function get_redirected_url($url)
{
    // 赋予全局变量
    global $headers, $uavalue;
    // 环境配置
    ini_set("user_agent", $uavalue);
    $context = stream_context_create([
        'http' => [
            'method' => 'GET',
            // 启用重定向
            'follow_location' => 1,
            // 最大重定向次数
            'max_redirects' => 5,
            'header' => $headers,
        ],
    ]);
    $response = file_get_contents($url, false, $context);
    foreach ($http_response_header as $header) {
        if (strpos($header, 'Location:') === 0) {
            return trim(substr($header, 9));
        }
    }
    return $url;
}

如果自己不想(不会)搭建的,也可以直接用我搭建好的。

地址:https://php-api.heheda.top/jiexi/douyin/

【请求方式和请求参数同上】

PS:稳定版接口已下线,并且后期不在提供稳定接口,此接口仅供测试,看心情维护,不保证稳定性。

如果有更好的实现思路或方法,欢迎大神前来交流!

本站资源均为作者提供和网友推荐收集整理而来,仅供学习和研究使用,请在下载后24小时内删除,谢谢合作!
抖音无水印解析源码分享及原理浅谈|不死鸟资源网
抖音无水印解析源码分享及原理浅谈
此内容为免费阅读,请登录后查看
¥0
限时特惠
¥99
文章采用CC BY-NC-SA 4.0许可协议授权
免费阅读
THE END
点赞15 分享