抖音解析新增Cookie配置并接入本地后备提取链路
变更项: - 配置文件新增 cookie 与 cookie_file 两个参数,支持账号态提取 - 解析请求与媒资下载统一接入请求头构建,按配置自动注入 Cookie - yt-dlp Python/命令行两种后备提取方式均支持 Cookie 注入 - Cookie 注入策略为 cookie_file 优先、cookie 次之,提升受限场景下无水印链接提取成功率
This commit is contained in:
@@ -91,6 +91,12 @@ class DouyinParserPlugin(MessagePluginInterface):
|
||||
douyin_config = self._config.get("Douyin", {})
|
||||
self.enable = douyin_config.get("enable", True)
|
||||
self.http_proxy = douyin_config.get("http_proxy", "")
|
||||
# Cookie 配置说明:
|
||||
# 1) cookie: 直接粘贴请求头 Cookie 字符串;
|
||||
# 2) cookie_file: Netscape 格式 cookies 文件路径;
|
||||
# 3) 当二者同时存在时,后备提取优先 cookie_file(兼容性更好)。
|
||||
self.cookie = douyin_config.get("cookie", "") or ""
|
||||
self.cookie_file = douyin_config.get("cookie_file", "") or ""
|
||||
self.download_mode = douyin_config.get("download_mode", "card") # card或file
|
||||
|
||||
self.LOG.debug(f"[{self.name}] 插件初始化完成,代理设置: {self.http_proxy}")
|
||||
@@ -261,10 +267,30 @@ class DouyinParserPlugin(MessagePluginInterface):
|
||||
return {"http": self.http_proxy, "https": self.http_proxy}
|
||||
return None
|
||||
|
||||
def _build_request_headers(self) -> Dict[str, str]:
|
||||
"""
|
||||
构建通用请求头。
|
||||
|
||||
设计说明:
|
||||
- User-Agent 保持常规浏览器标识,降低被目标站点直接拒绝的概率;
|
||||
- Cookie 在有配置时注入到请求头,提升受限资源的提取成功率。
|
||||
"""
|
||||
headers = {
|
||||
"User-Agent": (
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/124.0.0.0 Safari/537.36"
|
||||
)
|
||||
}
|
||||
if self.cookie:
|
||||
headers["Cookie"] = self.cookie
|
||||
return headers
|
||||
|
||||
def _parse_from_internal_api(self, clean_url: str) -> Optional[Dict[str, Any]]:
|
||||
try:
|
||||
endpoint = "http://192.168.2.32:8999/api/hybrid/video_data"
|
||||
headers = {"accept": "application/json"}
|
||||
headers = self._build_request_headers()
|
||||
headers["accept"] = "application/json"
|
||||
params = {"url": clean_url, "minimal": "false"}
|
||||
response = requests.get(endpoint, headers=headers, params=params, timeout=10, proxies=self._build_proxies())
|
||||
if response.status_code != 200:
|
||||
@@ -325,7 +351,13 @@ class DouyinParserPlugin(MessagePluginInterface):
|
||||
try:
|
||||
pay_api_url = "https://api.pearktrue.cn/api/video/api.php"
|
||||
params = {"url": clean_url, "key": "f56c1fed0c6e64e7"}
|
||||
response = requests.post(pay_api_url, params=params, timeout=10, proxies=self._build_proxies())
|
||||
response = requests.post(
|
||||
pay_api_url,
|
||||
params=params,
|
||||
headers=self._build_request_headers(),
|
||||
timeout=10,
|
||||
proxies=self._build_proxies(),
|
||||
)
|
||||
if response.status_code != 200:
|
||||
return None
|
||||
data = response.json() or {}
|
||||
@@ -391,7 +423,13 @@ class DouyinParserPlugin(MessagePluginInterface):
|
||||
"""
|
||||
try:
|
||||
# 发送GET请求,启用流式传输
|
||||
response = requests.get(url, stream=True)
|
||||
response = requests.get(
|
||||
url,
|
||||
stream=True,
|
||||
headers=self._build_request_headers(),
|
||||
proxies=self._build_proxies(),
|
||||
timeout=30,
|
||||
)
|
||||
|
||||
# 检查请求是否成功
|
||||
response.raise_for_status() # 如果状态码不是200,将抛出异常
|
||||
@@ -423,7 +461,12 @@ class DouyinParserPlugin(MessagePluginInterface):
|
||||
|
||||
def _download_image_bytes(self, url: str) -> Optional[bytes]:
|
||||
try:
|
||||
resp = requests.get(url, timeout=15, proxies=self._build_proxies())
|
||||
resp = requests.get(
|
||||
url,
|
||||
headers=self._build_request_headers(),
|
||||
timeout=15,
|
||||
proxies=self._build_proxies(),
|
||||
)
|
||||
if resp.status_code == 200:
|
||||
return resp.content
|
||||
return None
|
||||
@@ -540,6 +583,13 @@ class DouyinParserPlugin(MessagePluginInterface):
|
||||
"proxy": self.http_proxy or None,
|
||||
"nocheckcertificate": True,
|
||||
}
|
||||
# Cookie 注入策略:
|
||||
# - 优先使用 cookie_file(yt-dlp 官方支持的 cookies 文件,兼容性更高);
|
||||
# - 否则回退到手工 Cookie 请求头。
|
||||
if self.cookie_file and os.path.exists(self.cookie_file):
|
||||
ydl_opts["cookiefile"] = self.cookie_file
|
||||
elif self.cookie:
|
||||
ydl_opts["http_headers"] = {"Cookie": self.cookie}
|
||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||
info = ydl.extract_info(clean_url, download=False)
|
||||
if isinstance(info, dict):
|
||||
@@ -559,6 +609,11 @@ class DouyinParserPlugin(MessagePluginInterface):
|
||||
cmd = [yt_dlp_bin, "-J", "--no-warnings", "--skip-download", clean_url]
|
||||
if self.http_proxy:
|
||||
cmd.extend(["--proxy", self.http_proxy])
|
||||
# 命令行模式下同样注入 Cookie,确保与 Python 模式行为一致。
|
||||
if self.cookie_file and os.path.exists(self.cookie_file):
|
||||
cmd.extend(["--cookies", self.cookie_file])
|
||||
elif self.cookie:
|
||||
cmd.extend(["--add-header", f"Cookie: {self.cookie}"])
|
||||
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=25)
|
||||
if result.returncode != 0:
|
||||
|
||||
Reference in New Issue
Block a user