71 lines
2.2 KiB
Python
71 lines
2.2 KiB
Python
"""抖音直播间页面临时解析主播昵称(仅供控制台展示,可能随页面改版失效)。"""
|
||
from __future__ import annotations
|
||
|
||
import re
|
||
import urllib.error
|
||
import urllib.request
|
||
from typing import Any
|
||
|
||
|
||
_UA = (
|
||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
|
||
"(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||
)
|
||
|
||
|
||
def _norm_douyin_live_url(url: str) -> str:
|
||
u = (url or "").strip()
|
||
if not u:
|
||
return ""
|
||
u = u.split("#")[0].strip()
|
||
if u.startswith("http://"):
|
||
u = "https://" + u[7:]
|
||
if not u.startswith("https://"):
|
||
u = "https://" + u
|
||
return u
|
||
|
||
|
||
def _room_id_from_url(url: str) -> str:
|
||
m = re.search(r"live\.douyin\.com/([a-zA-Z0-9_-]+)", url, re.I)
|
||
return m.group(1) if m else ""
|
||
|
||
|
||
def fetch_douyin_anchor_name(url: str) -> dict[str, Any]:
|
||
u = _norm_douyin_live_url(url)
|
||
if not re.search(r"douyin\.com", u, re.I):
|
||
return {"ok": False, "error": "非抖音链接", "url": url, "room_id": "", "anchor_name": ""}
|
||
rid = _room_id_from_url(u)
|
||
if not rid:
|
||
return {"ok": False, "error": "无法解析房间号", "url": url, "room_id": "", "anchor_name": ""}
|
||
try:
|
||
req = urllib.request.Request(u, headers={"User-Agent": _UA, "Accept": "text/html,*/*"})
|
||
with urllib.request.urlopen(req, timeout=12) as resp:
|
||
html = resp.read().decode("utf-8", errors="ignore")
|
||
except urllib.error.HTTPError as e:
|
||
return {"ok": False, "error": f"HTTP {e.code}", "url": u, "room_id": rid, "anchor_name": ""}
|
||
except Exception as e:
|
||
return {"ok": False, "error": str(e), "url": u, "room_id": rid, "anchor_name": ""}
|
||
|
||
name = ""
|
||
for pat in (
|
||
r'"nickname"\s*:\s*"([^"\\]+)"',
|
||
r'"nickName"\s*:\s*"([^"\\]+)"',
|
||
r'"owner"\s*:\s*\{[^}]*"nickname"\s*:\s*"([^"\\]+)"',
|
||
):
|
||
m = re.search(pat, html)
|
||
if m:
|
||
name = m.group(1).strip()
|
||
break
|
||
if not name:
|
||
m2 = re.search(r"主播[::]\s*([^\s<\"]{1,40})", html)
|
||
if m2:
|
||
name = m2.group(1).strip()
|
||
|
||
return {
|
||
"ok": True,
|
||
"url": u,
|
||
"room_id": rid,
|
||
"anchor_name": name or "",
|
||
"error": "" if name else "未解析到昵称",
|
||
}
|