Files
douyin_video_download/douyin/urls.py
whale-fall-code 2bb83f3685 初始提交:抖音视频批量采集流水线
App 端免签名接口(设备注册 + detail + CDN 直链),一体化流水线
下载→抽音→传COS→记录→删本地,AI 作品四档判定,四份文档:
README(使用指南)、PROGRESS(批次进度)、RE(逆向全过程)、AI(判定规则)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-29 16:31:10 +08:00

86 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""链接解析:把用户随手粘的东西还原成 aweme_id。
支持的输入形态:
7xxxxxxxxxxxxxxxxxx 裸 id
https://v.douyin.com/xxxxxxx/ 分享短链(需要一次网络跳转)
4.53 复制打开抖音... https://v.douyin.com/xxx/ ... 整段分享口令
https://www.douyin.com/video/7xxxxxx
https://www.douyin.com/note/7xxxxxx 图文
https://www.douyin.com/?modal_id=7xxxxxx
https://www.iesdouyin.com/share/video/7xxxxxx/
"""
from __future__ import annotations
import re
from typing import Optional
import requests
# 从一段中文分享口令里把 url 抠出来
URL_RE = re.compile(r"https?://[-\w./?=&%#:]+")
SHORT_HOSTS = ("v.douyin.com", "v.iesdouyin.com")
# 按优先级尝试的 id 提取规则
ID_PATTERNS = (
re.compile(r"/(?:video|note|slides|share/video|share/note)/(\d{15,25})"),
re.compile(r"[?&](?:modal_id|aweme_id|item_ids|vid)=(\d{15,25})"),
)
BARE_ID_RE = re.compile(r"^\d{15,25}$")
class ParseError(ValueError):
"""输入里找不到可用的 aweme_id。"""
def _first_url(text: str) -> Optional[str]:
m = URL_RE.search(text)
return m.group(0) if m else None
def _extract_id(url: str) -> Optional[str]:
for pat in ID_PATTERNS:
m = pat.search(url)
if m:
return m.group(1)
return None
def resolve_short_link(url: str, session: requests.Session, timeout: float = 15.0) -> str:
"""跟随 v.douyin.com 短链跳转,返回落地长链。"""
resp = session.get(url, timeout=timeout, allow_redirects=True)
return resp.url
def extract_aweme_id(raw: str, session: Optional[requests.Session] = None) -> str:
"""从任意输入中解析出 aweme_id,必要时联网还原短链。"""
raw = raw.strip()
if BARE_ID_RE.match(raw):
return raw
url = _first_url(raw)
if not url:
raise ParseError(f"输入里没找到链接也不是纯数字 id: {raw[:80]!r}")
aid = _extract_id(url)
if aid:
return aid
if any(h in url for h in SHORT_HOSTS):
if session is None:
session = requests.Session()
session.headers["User-Agent"] = (
"Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) "
"AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 "
"Mobile/15E148 Safari/604.1"
)
final = resolve_short_link(url, session)
aid = _extract_id(final)
if aid:
return aid
raise ParseError(f"短链 {url} 跳转到 {final},但里面没有 aweme_id")
raise ParseError(f"无法从 {url} 中解析出 aweme_id")