December 5, 2025
212 Views
Default

Guía de descarga de enlaces de vídeo multiplataforma

Este documento detalla cómo descargar archivos de video correctamente después de obtener enlaces de video de Douyin, TikTok, Bilibili, Xiaohongshu, Weibo y otras plataformas. Concéntrese en resolver problemas comunes como la verificación de encabezados de solicitud, anti-hotlinking y entre dominios.

多平台视频链接下载指南

本文档详细介绍从抖音、TikTok、哔哩哔哩、小红书、微博等平台获取视频链接后,如何正确下载视频文件。重点解决跨域、防盗链、请求头验证等常见问题。

目录


通用问题概述

从各平台获取到视频链接后,直接下载通常会遇到以下问题:

问题类型描述解决方案
防盗链 (Referer)服务器检查请求来源,拒绝非法来源设置正确的 Referer 头
跨域 (CORS)浏览器安全策略阻止跨域请求后端代理 / 服务端下载
User-Agent 验证服务器检查客户端标识模拟浏览器 UA
Cookie 验证部分链接需要登录态携带有效 Cookie
链接时效性视频链接有过期时间及时使用,过期重新获取
IP 限制部分链接限制访问地区使用对应地区代理

抖音 (Douyin)

视频链接特点

抖音视频链接通常有以下几种形式:

txt
1# 播放地址 (无水印)
2https://www.douyin.com/aweme/v1/play/?video_id=xxx&line=0&file_id=xxx
3
4# CDN 地址
5https://v26-web.douyinvod.com/xxx/xxx.mp4
6
7# 带水印下载地址
8https://aweme.snssdk.com/aweme/v1/playwm/?video_id=xxx

下载要求

请求头是否必须
Referer必须https://www.douyin.com/
User-Agent推荐浏览器 UA
Cookie可选部分高清链接需要

服务端下载示例

python
1import httpx
2
3async def download_douyin_video(video_url: str, save_path: str) -> bool:
4    """
5    下载抖音视频
6
7    Args:
8        video_url: 视频播放地址
9        save_path: 保存路径
10
11    Returns:
12        是否下载成功
13    """
14    headers = {
15        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
16        "Referer": "https://www.douyin.com/",  # 必须
17        "Accept": "*/*",
18        "Accept-Encoding": "identity",  # 避免压缩,方便流式下载
19        "Range": "bytes=0-",  # 支持断点续传
20    }
21
22    async with httpx.AsyncClient(follow_redirects=True, timeout=60) as client:
23        async with client.stream("GET", video_url, headers=headers) as response:
24            if response.status_code in [200, 206]:
25                with open(save_path, "wb") as f:
26                    async for chunk in response.aiter_bytes(chunk_size=8192):
27                        f.write(chunk)
28                return True
29    return False

前端跨域问题

抖音视频链接不支持 CORS,前端直接请求会被浏览器拦截:

javascript
1// ❌ 错误方式 - 会被 CORS 拦截
2fetch('https://v26-web.douyinvod.com/xxx.mp4')
3  .then(res => res.blob())  // CORS error!
4
5// ✅ 正确方式 - 使用后端代理
6fetch('/api/proxy/video?url=' + encodeURIComponent(videoUrl))
7  .then(res => res.blob())
8  .then(blob => {
9    const url = URL.createObjectURL(blob);
10    const a = document.createElement('a');
11    a.href = url;
12    a.download = 'video.mp4';
13    a.click();
14  });

注意事项

  1. 链接时效性: 抖音视频链接通常在 24 小时 内有效
  2. 无水印链接: 使用 play_addr 而非 download_addr
  3. 高清链接: 部分 4K/原画视频大小较大,建议使用分段下载,避免一次性下载失败

TikTok

视频链接特点

txt
1# 播放地址
2https://v16-webapp-prime.tiktok.com/video/tos/xxx.mp4
3
4# 无水印地址
5https://www.tiktok.com/aweme/v1/play/?video_id=xxx
6
7# 带水印地址
8https://v16-webapp.tiktok.com/video/tos/xxx.mp4

下载要求

Web 端视频链接

请求头是否必须
Referer必须https://www.tiktok.com/
User-Agent必须浏览器 UA
Cookie必须需要 tt_chain_token 字段

重要: TikTok Web 端返回的视频链接必须携带 tt_chain_token Cookie 才能下载,否则会返回 403 错误。

App 端视频链接

请求头是否必须
User-Agent推荐任意 UA
Cookie不需要App 端链接无此限制

推荐: 如果可以获取 App 端链接,优先使用 App 端链接,无需处理 Cookie 问题。

服务端下载示例

Web 端下载 (需要 tt_chain_token)

python
1import httpx
2
3async def download_tiktok_video_web(
4    video_url: str,
5    save_path: str,
6    tt_chain_token: str  # 必须提供
7) -> bool:
8    """
9    下载 TikTok Web 端视频
10
11    注意:
12    - Web 端链接必须携带 tt_chain_token Cookie
13    - tt_chain_token 可从浏览器或 API 响应中获取
14    """
15    headers = {
16        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
17        "Referer": "https://www.tiktok.com/",
18        "Accept": "video/webm,video/ogg,video/*;q=0.9,*/*;q=0.8",
19        "Accept-Language": "en-US,en;q=0.5",
20        "Cookie": f"tt_chain_token={tt_chain_token}",  # 必须
21        "Sec-Fetch-Dest": "video",
22        "Sec-Fetch-Mode": "no-cors",
23        "Sec-Fetch-Site": "cross-site",
24    }
25
26    async with httpx.AsyncClient(follow_redirects=True, timeout=60) as client:
27        async with client.stream("GET", video_url, headers=headers) as response:
28            if response.status_code in [200, 206]:
29                with open(save_path, "wb") as f:
30                    async for chunk in response.aiter_bytes(chunk_size=8192):
31                        f.write(chunk)
32                return True
33            elif response.status_code == 403:
34                print("下载失败: tt_chain_token 无效或缺失")
35    return False
python
1async def download_tiktok_video_app(video_url: str, save_path: str) -> bool:
2    """
3    下载 TikTok App 端视频
4
5    App 端链接无需 Cookie,直接下载即可
6    """
7    headers = {
8        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
9        "Accept": "*/*",
10    }
11
12    async with httpx.AsyncClient(follow_redirects=True, timeout=60) as client:
13        async with client.stream("GET", video_url, headers=headers) as response:
14            if response.status_code in [200, 206]:
15                with open(save_path, "wb") as f:
16                    async for chunk in response.aiter_bytes(chunk_size=8192):
17                        f.write(chunk)
18                return True
19    return False

如何获取 tt_chain_token

tt_chain_token 是 TikTok 用于视频下载鉴权的 Cookie,获取方式:

  1. 从浏览器获取: 打开 TikTok 网站,F12 开发者工具 -> Application -> Cookies -> 找到 tt_chain_token

  2. 从 API 响应获取: 部分 TikTok API 响应的 Set-Cookie 头中会包含此值

  3. 使用 TikHub API: API 返回数据中可能已包含可用的 token

python
1# 示例:从响应头提取 tt_chain_token
2def extract_tt_chain_token(response_headers: dict) -> str:
3    """从响应头中提取 tt_chain_token"""
4    cookies = response_headers.get("set-cookie", "")
5    for cookie in cookies.split(";"):
6        if "tt_chain_token=" in cookie:
7            return cookie.split("tt_chain_token=")[1].split(";")[0]
8    return ""

地区限制

TikTok 视频可能有地区限制,部分视频仅在特定国家可访问:

python
1# 使用代理下载特定地区视频
2proxies = {
3    "http://": "http://us-proxy:8080",
4    "https://": "http://us-proxy:8080",
5}
6
7async with httpx.AsyncClient(proxies=proxies) as client:
8    # ...

注意事项

  1. 地区限制: 部分视频需要美国/欧洲 IP 才能访问
  2. 链接时效性: 链接有效期约 24 小时
  3. 无水印: 优先使用 downloadAddr 字段

哔哩哔哩 (Bilibili)

视频链接特点

B站视频链接比较特殊,音频和视频是分离的

txt
1# 视频流 (DASH)
2https://upos-sz-mirrorali.bilivideo.com/xxx/xxx.m4s
3
4# 音频流 (DASH)
5https://upos-sz-mirrorali.bilivideo.com/xxx/xxx.m4s
6
7# FLV 格式 (旧版)
8https://upos-sz-mirrorali.bilivideo.com/xxx/xxx.flv

下载要求

请求头是否必须
Referer必须https://www.bilibili.com/
User-Agent推荐浏览器 UA
Cookie高清,4K必须SESSDATA 等
Range推荐分段下载

服务端下载示例

python
1import httpx
2import subprocess
3from pathlib import Path
4
5async def download_bilibili_video(
6    video_url: str,
7    audio_url: str,
8    save_path: str,
9    cookie: str = None
10) -> bool:
11    """
12    下载 B站 视频 (需要合并音视频)
13
14    Args:
15        video_url: 视频流地址
16        audio_url: 音频流地址
17        save_path: 最终保存路径
18        cookie: 可选,高清视频需要 SESSDATA
19    """
20    headers = {
21        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
22        "Referer": "https://www.bilibili.com/",  # 必须,否则 403
23        "Accept": "*/*",
24        "Accept-Encoding": "identity",
25        "Origin": "https://www.bilibili.com",
26    }
27
28    if cookie:
29        headers["Cookie"] = cookie
30
31    # 临时文件路径
32    video_temp = save_path + ".video.m4s"
33    audio_temp = save_path + ".audio.m4s"
34
35    async with httpx.AsyncClient(follow_redirects=True, timeout=120) as client:
36        # 下载视频流
37        async with client.stream("GET", video_url, headers=headers) as response:
38            if response.status_code not in [200, 206]:
39                return False
40            with open(video_temp, "wb") as f:
41                async for chunk in response.aiter_bytes(chunk_size=8192):
42                    f.write(chunk)
43
44        # 下载音频流
45        async with client.stream("GET", audio_url, headers=headers) as response:
46            if response.status_code not in [200, 206]:
47                return False
48            with open(audio_temp, "wb") as f:
49                async for chunk in response.aiter_bytes(chunk_size=8192):
50                    f.write(chunk)
51
52    # 使用 FFmpeg 合并音视频
53    try:
54        subprocess.run([
55            "ffmpeg", "-y",
56            "-i", video_temp,
57            "-i", audio_temp,
58            "-c:v", "copy",
59            "-c:a", "copy",
60            save_path
61        ], check=True, capture_output=True)
62
63        # 删除临时文件
64        Path(video_temp).unlink()
65        Path(audio_temp).unlink()
66        return True
67    except subprocess.CalledProcessError:
68        return False
画质是否需要登录Cookie 要求
360P/480P
720PSESSDATA
1080PSESSDATA + 大会员
4K/HDRSESSDATA + 大会员

注意事项

  1. 必须合并: DASH 格式音视频分离,需用 FFmpeg 合并
  2. Referer 必须: 没有正确 Referer 会返回 403
  3. 链接时效性: 约 2 小时 有效
  4. 分段下载: 大文件建议使用 Range 头分段下载

小红书 (Xiaohongshu)

视频链接特点

txt
1# 视频地址
2https://sns-video-bd.xhscdn.com/xxx.mp4
3https://sns-video-hw.xhscdn.com/xxx.mp4
4
5# 图片地址
6https://sns-img-bd.xhscdn.com/xxx.jpg

下载要求

请求头是否必须
Referer必须https://www.xiaohongshu.com/
User-Agent推荐浏览器 UA
Cookie可选部分内容需要

服务端下载示例

python
1import httpx
2
3async def download_xiaohongshu_video(video_url: str, save_path: str) -> bool:
4    """
5    下载小红书视频
6
7    小红书对 Referer 检查较严格
8    """
9    headers = {
10        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
11        "Referer": "https://www.xiaohongshu.com/",  # 必须
12        "Accept": "*/*",
13        "Origin": "https://www.xiaohongshu.com",
14        "Sec-Fetch-Dest": "video",
15        "Sec-Fetch-Mode": "cors",
16        "Sec-Fetch-Site": "cross-site",
17    }
18
19    async with httpx.AsyncClient(follow_redirects=True, timeout=60) as client:
20        async with client.stream("GET", video_url, headers=headers) as response:
21            if response.status_code in [200, 206]:
22                with open(save_path, "wb") as f:
23                    async for chunk in response.aiter_bytes(chunk_size=8192):
24                        f.write(chunk)
25                return True
26    return False

图片下载

小红书图片同样有防盗链:

python
1async def download_xiaohongshu_image(image_url: str, save_path: str) -> bool:
2    """下载小红书图片"""
3    headers = {
4        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
5        "Referer": "https://www.xiaohongshu.com/",
6        "Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8",
7    }
8
9    async with httpx.AsyncClient(follow_redirects=True) as client:
10        response = await client.get(image_url, headers=headers)
11        if response.status_code == 200:
12            with open(save_path, "wb") as f:
13                f.write(response.content)
14            return True
15    return False

注意事项

  1. Referer 严格: 必须带 xiaohongshu.com 的 Referer
  2. CDN 节点: bd (百度云)、hw (华为云) 等不同节点
  3. 无水印: API 返回的链接通常是无水印的

微博 (Weibo)

视频链接特点

微博视频链接格式较多:

txt
1# 标准视频
2https://f.video.weibocdn.com/xxx.mp4
3
4# 直播回放
5https://live.video.weibocdn.com/xxx.flv
6
7# 高清视频
8https://video.weibo.com/media/play?fid=xxx

下载要求

请求头是否必须
Referer必须https://weibo.com/https://m.weibo.cn/
User-Agent推荐浏览器 UA
Cookie部分需要私密视频需要

服务端下载示例

python
1import httpx
2
3async def download_weibo_video(video_url: str, save_path: str) -> bool:
4    """
5    下载微博视频
6
7    微博支持多个 Referer 域名
8    """
9    headers = {
10        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
11        "Referer": "https://weibo.com/",  # 或 https://m.weibo.cn/
12        "Accept": "*/*",
13        "Accept-Encoding": "identity",
14    }
15
16    async with httpx.AsyncClient(follow_redirects=True, timeout=60) as client:
17        async with client.stream("GET", video_url, headers=headers) as response:
18            if response.status_code in [200, 206]:
19                with open(save_path, "wb") as f:
20                    async for chunk in response.aiter_bytes(chunk_size=8192):
21                        f.write(chunk)
22                return True
23    return False

多清晰度选择

微博视频通常提供多个清晰度:

python
1def select_best_quality(media_info: dict) -> str:
2    """选择最高清晰度的视频链接"""
3    # 清晰度优先级
4    quality_priority = ["mp4_720p_mp4", "mp4_hd_mp4", "mp4_ld_mp4"]
5
6    playback_list = media_info.get("playback_list", [])
7
8    for quality in quality_priority:
9        for item in playback_list:
10            if item.get("quality_label") == quality:
11                return item.get("play_info", {}).get("url")
12
13    # 降级使用 stream_url
14    return media_info.get("stream_url")

注意事项

  1. Referer 域名: 支持 weibo.comm.weibo.cn
  2. 多清晰度: 返回数据中有多个清晰度可选
  3. 链接时效: 部分链接有时效限制

YouTube

视频链接特点

YouTube 视频链接通常有以下几种形式:

txt
1# 标准视频流地址
2https://rr1---sn-xxx.googlevideo.com/videoplayback?expire=xxx&ei=xxx&ip=xxx&id=xxx&itag=xxx&source=youtube&...
3
4# 自适应流地址 (DASH)
5https://manifest.googlevideo.com/api/manifest/dash/...
6
7# 直播流地址 (HLS)
8https://manifest.googlevideo.com/api/manifest/hls_variant/...

下载要求

严格 IP 限制: YouTube 视频流地址对 IP 地理位置有极其严格的验证,必须使用美国加利福尼亚州洛杉矶地区的 IP 才能成功下载,否则会返回 403 Forbidden 错误。

请求头是否必须
User-Agent必须浏览器 UA
Referer推荐https://www.youtube.com/
Origin推荐https://www.youtube.com
代理 IP必须美国加州洛杉矶 IP

IP 地区限制说明

YouTube 的视频流地址在生成时会绑定请求者的 IP 地址,下载时必须使用相同地区的 IP:

txt
1# 视频流 URL 中包含 IP 绑定参数
2https://rr1---sn-xxx.googlevideo.com/videoplayback?
3    expire=1234567890        # 过期时间
4    &ei=xxx                  # 加密标识
5    &ip=1.2.3.4             # 绑定的 IP 地址 (关键!)
6    &id=xxx
7    &itag=137               # 视频质量标识
8    &source=youtube
9    &...

为什么必须是洛杉矶 IP?

  1. YouTube 大部分 CDN 节点位于美国西海岸
  2. 视频流 URL 生成时会根据请求 IP 选择最近的 CDN
  3. 下载时 IP 地区不匹配会导致 403 错误
  4. 洛杉矶是 YouTube 主要的数据中心所在地,兼容性最好

服务端下载示例

python
1import httpx
2
3async def download_youtube_video(
4    video_url: str,
5    save_path: str,
6    proxy: str = None  # 必须是美国加州洛杉矶代理
7) -> bool:
8    """
9    下载 YouTube 视频
10
11    重要:
12    - 必须使用美国加利福尼亚州洛杉矶地区的代理 IP
13    - 其他地区 IP 会返回 403 Forbidden
14    - 视频流 URL 有时效性,通常 6 小时内有效
15    """
16    headers = {
17        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
18        "Referer": "https://www.youtube.com/",
19        "Origin": "https://www.youtube.com",
20        "Accept": "*/*",
21        "Accept-Language": "en-US,en;q=0.9",
22        "Accept-Encoding": "identity",  # 避免压缩
23        "Range": "bytes=0-",  # 支持断点续传
24        "Sec-Fetch-Dest": "video",
25        "Sec-Fetch-Mode": "no-cors",
26        "Sec-Fetch-Site": "cross-site",
27    }
28
29    # 代理配置 - 必须是洛杉矶 IP
30    proxies = None
31    if proxy:
32        proxies = {
33            "http://": proxy,
34            "https://": proxy,
35        }
36
37    async with httpx.AsyncClient(
38        follow_redirects=True,
39        timeout=120,
40        proxies=proxies
41    ) as client:
42        async with client.stream("GET", video_url, headers=headers) as response:
43            if response.status_code in [200, 206]:
44                with open(save_path, "wb") as f:
45                    async for chunk in response.aiter_bytes(chunk_size=8192):
46                        f.write(chunk)
47                return True
48            elif response.status_code == 403:
49                print("下载失败: IP 地区不符合要求,请使用美国加州洛杉矶的代理")
50            elif response.status_code == 410:
51                print("下载失败: 视频链接已过期,请重新获取")
52    return False

音视频分离处理

YouTube 高清视频 (1080p+) 采用 DASH 格式,音频和视频是分离的:

python
1import subprocess
2from pathlib import Path
3
4async def download_youtube_video_with_audio(
5    video_url: str,
6    audio_url: str,
7    save_path: str,
8    proxy: str = None
9) -> bool:
10    """
11    下载 YouTube 视频并合并音频
12
13    YouTube 1080p 及以上清晰度的视频,音频和视频是分离的
14    需要分别下载后使用 FFmpeg 合并
15    """
16    video_temp = save_path + ".video.mp4"
17    audio_temp = save_path + ".audio.m4a"
18
19    # 下载视频流
20    success = await download_youtube_video(video_url, video_temp, proxy)
21    if not success:
22        return False
23
24    # 下载音频流
25    success = await download_youtube_video(audio_url, audio_temp, proxy)
26    if not success:
27        return False
28
29    # 使用 FFmpeg 合并
30    try:
31        subprocess.run([
32            "ffmpeg", "-y",
33            "-i", video_temp,
34            "-i", audio_temp,
35            "-c:v", "copy",
36            "-c:a", "aac",
37            save_path
38        ], check=True, capture_output=True)
39
40        # 删除临时文件
41        Path(video_temp).unlink()
42        Path(audio_temp).unlink()
43        return True
44    except subprocess.CalledProcessError as e:
45        print(f"FFmpeg 合并失败: {e}")
46        return False

代理配置示例

python
1# 推荐的代理配置 - 必须是洛杉矶地区
2LA_PROXIES = [
3    "http://user:pass@la-proxy1.example.com:8080",  # 洛杉矶代理 1
4    "http://user:pass@la-proxy2.example.com:8080",  # 洛杉矶代理 2
5    "socks5://user:pass@la-socks.example.com:1080", # SOCKS5 代理
6]
7
8# 验证代理 IP 是否在洛杉矶
9async def verify_proxy_location(proxy: str) -> bool:
10    """验证代理 IP 是否在洛杉矶地区"""
11    async with httpx.AsyncClient(proxies={"https://": proxy}) as client:
12        response = await client.get("https://ipapi.co/json/")
13        data = response.json()
14
15        city = data.get("city", "")
16        region = data.get("region", "")
17        country = data.get("country_code", "")
18
19        # 检查是否在加州洛杉矶
20        is_la = (
21            country == "US" and
22            region == "California" and
23            "Los Angeles" in city
24        )
25
26        if is_la:
27            print(f"✓ 代理 IP 位于: {city}, {region}, {country}")
28        else:
29            print(f"✗ 代理 IP 位于: {city}, {region}, {country} (不符合要求)")
30
31        return is_la

画质标识 (itag) 对照表

itag分辨率格式是否包含音频
18360pMP4
22720pMP4
1371080pMP4 (需合并)
2481080pWebM (需合并)
2711440pWebM (需合并)
3132160pWebM (需合并)
140-M4A 音频仅音频
251-WebM 音频仅音频

注意事项

  1. IP 限制极严格: 必须使用美国加州洛杉矶的 IP,其他地区 (包括美国其他州) 都可能失败
  2. 链接时效性: 视频流 URL 通常在 6 小时 内有效
  3. 音视频分离: 720p 以上清晰度需要分别下载音频和视频后合并
  4. 速率限制: YouTube 对下载速度有限制,大文件建议分段下载
  5. 版权保护: 部分视频有 DRM 保护,无法直接下载

前端下载方案

由于 CORS 限制,前端无法直接下载大部分平台的视频。以下是可行的方案:

方案一:后端代理 (推荐)

javascript
1// 前端请求后端代理接口
2async function downloadVideo(videoUrl, platform, filename) {
3  const proxyUrl = `/api/download/video?url=${encodeURIComponent(videoUrl)}&platform=${platform}`;
4
5  const response = await fetch(proxyUrl);
6  const blob = await response.blob();
7
8  // 创建下载链接
9  const url = URL.createObjectURL(blob);
10  const a = document.createElement('a');
11  a.href = url;
12  a.download = filename || 'video.mp4';
13  document.body.appendChild(a);
14  a.click();
15  document.body.removeChild(a);
16  URL.revokeObjectURL(url);
17}

方案二:新窗口打开 (部分平台可用)

javascript
1// 部分平台链接可以直接在新窗口打开下载
2function openVideoInNewTab(videoUrl) {
3  window.open(videoUrl, '_blank');
4}

方案三:使用 download 属性 (同源场景)

html
1<!-- 仅适用于同源或允许 CORS 的资源 -->
2<a href="video.mp4" download="video.mp4">下载视频</a>

后端代理下载方案

FastAPI 代理示例

python
1from fastapi import FastAPI, Query, Response
2from fastapi.responses import StreamingResponse
3import httpx
4
5app = FastAPI()
6
7# 各平台的请求头配置
8PLATFORM_HEADERS = {
9    "douyin": {
10        "Referer": "https://www.douyin.com/",
11        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
12    },
13    "tiktok": {
14        "Referer": "https://www.tiktok.com/",
15        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
16    },
17    "bilibili": {
18        "Referer": "https://www.bilibili.com/",
19        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
20    },
21    "xiaohongshu": {
22        "Referer": "https://www.xiaohongshu.com/",
23        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
24    },
25    "weibo": {
26        "Referer": "https://weibo.com/",
27        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
28    },
29}
30
31
32@app.get("/api/download/video")
33async def proxy_video(
34    url: str = Query(..., description="视频 URL"),
35    platform: str = Query(..., description="平台标识"),
36):
37    """
38    视频代理下载接口
39
40    解决前端跨域和防盗链问题
41    """
42    headers = PLATFORM_HEADERS.get(platform, {})
43
44    async def video_stream():
45        async with httpx.AsyncClient(follow_redirects=True, timeout=120) as client:
46            async with client.stream("GET", url, headers=headers) as response:
47                async for chunk in response.aiter_bytes(chunk_size=8192):
48                    yield chunk
49
50    return StreamingResponse(
51        video_stream(),
52        media_type="video/mp4",
53        headers={
54            "Content-Disposition": "attachment; filename=video.mp4",
55            "Access-Control-Allow-Origin": "*",  # 允许跨域
56        }
57    )
58
59
60@app.get("/api/download/image")
61async def proxy_image(
62    url: str = Query(..., description="图片 URL"),
63    platform: str = Query(..., description="平台标识"),
64):
65    """图片代理下载接口"""
66    headers = PLATFORM_HEADERS.get(platform, {})
67
68    async with httpx.AsyncClient(follow_redirects=True) as client:
69        response = await client.get(url, headers=headers)
70
71        return Response(
72            content=response.content,
73            media_type=response.headers.get("content-type", "image/jpeg"),
74            headers={
75                "Access-Control-Allow-Origin": "*",
76            }
77        )

带进度的下载示例

python
1import httpx
2from tqdm import tqdm
3
4async def download_with_progress(url: str, save_path: str, headers: dict) -> bool:
5    """带进度条的下载"""
6    async with httpx.AsyncClient(follow_redirects=True, timeout=120) as client:
7        async with client.stream("GET", url, headers=headers) as response:
8            total = int(response.headers.get("content-length", 0))
9
10            with open(save_path, "wb") as f:
11                with tqdm(total=total, unit="B", unit_scale=True, desc="下载中") as pbar:
12                    async for chunk in response.aiter_bytes(chunk_size=8192):
13                        f.write(chunk)
14                        pbar.update(len(chunk))
15
16            return True
17    return False

总结

各平台下载要点速查表

平台RefererCookie 要求特殊处理链接有效期
抖音https://www.douyin.com/可选24 小时
TikTok Webhttps://www.tiktok.com/必须 tt_chain_token需要地区代理1-6 小时
TikTok App不需要不需要推荐使用较长
B站https://www.bilibili.com/高清必须 SESSDATA音视频分离需合并2 小时
小红书https://www.xiaohongshu.com/可选较长
微博https://weibo.com/部分需要多清晰度较长
YouTubehttps://www.youtube.com/不需要必须洛杉矶 IP + 音视频分离6 小时

常见错误排查

错误码可能原因解决方案
403 ForbiddenReferer 错误或缺失检查 Referer 头
403 ForbiddenTikTok 缺少 tt_chain_token添加 Cookie 或使用 App 端链接
403 ForbiddenYouTube IP 地区不符使用美国加州洛杉矶代理
404 Not Found链接过期重新获取链接
410 GoneYouTube 链接过期重新获取视频流 URL
CORS Error浏览器跨域限制使用后端代理
超时网络问题或文件过大增加超时时间,分段下载

最佳实践

  1. 始终设置 Referer: 这是大部分平台的必要条件
  2. 使用后端代理: 解决前端 CORS 问题的最佳方案
  3. 处理链接时效: 及时使用链接,过期重新获取
  4. 支持断点续传: 大文件使用 Range 头分段下载
  5. 错误重试: 网络不稳定时实现重试机制

联系我们

如果您按照本文档的指引操作后仍然无法成功下载视频,请联系客服获取帮助:

在联系客服时,请提供以下信息以便我们更快地帮助您:

  1. 平台名称: 抖音/TikTok/B站/小红书/微博/YouTube
  2. 视频链接: 原始视频页面 URL
  3. 错误信息: 完整的错误码和错误描述
  4. 请求头配置: 您使用的 Referer、Cookie 等信息
  5. 代理信息: 如使用代理,请提供代理地区

Enjoyed this article?

Share it with your friends and colleagues!

Default
Last updated: April 4, 2026
相关文章
正在检查服务状态...
多平台视频链接下载指南 - TikHub.io