# -*- coding: utf-8 -*- """只读接口的身份校验探测:对比 完整 cookie / 无 cookie / 去掉身份字段 三种情况。 用法: python tools/probe_anon.py """ import json import os import sys import time import urllib.parse import urllib.request ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, ROOT) sys.stdout.reconfigure(encoding="utf-8") from favsort import strip_identity # noqa: E402 与主程序保持同一套剥离规则 BASE = "https://api.bilibili.com" UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36") BASE_HEADERS = { "accept": "*/*", "accept-language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7", "dnt": "1", "origin": "https://www.bilibili.com", "referer": "https://www.bilibili.com/", "sec-ch-ua": '"Google Chrome";v="155", "Chromium";v="155", "Not(A:Brand";v="24"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": '"Windows"', "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-site", "user-agent": UA, } def get(url, cookie): headers = dict(BASE_HEADERS) if cookie is not None: headers["cookie"] = cookie req = urllib.request.Request(url, headers=headers) try: with urllib.request.urlopen(req, timeout=30) as r: return json.loads(r.read().decode("utf-8", "replace")) except Exception as e: # noqa: BLE001 return {"code": "EXC", "message": str(e)[:60]} def main(): cfg = json.load(open(os.path.join(ROOT, "config.json"), encoding="utf-8")) full = cfg["cookie"] anon = strip_identity(full) variants = [("完整 cookie", full), ("去掉身份字段", anon), ("完全无 cookie", None)] folders = [(3700023351, "咻咻满 reaction 合集 (658)"), (4451053851, "咻咻满-reaction-2025 (167)"), (85420451, "默认收藏夹 (29)")] print("=== ids 接口 ===") for name, ck in variants: for mid, label in folders: url = f"{BASE}/x/v3/fav/resource/ids?media_id={mid}&platform=web" r = get(url, ck) n = len(r.get("data") or []) if isinstance(r.get("data"), list) else "-" print(f" [{name:<14}] media={mid:<11} code={r.get('code')!s:<5} " f"条数={n!s:<5} msg={r.get('message')}") time.sleep(1.2) print() print("=== infos 接口(各取前 3 条)===") for mid, label in folders: ids = get(f"{BASE}/x/v3/fav/resource/ids?media_id={mid}&platform=web", full) arr = ids.get("data") or [] res = ",".join(f"{x['id']}:{x['type']}" for x in arr[:3]) if not res: print(f" media={mid}: 没有可测资源") continue for name, ck in variants: url = (f"{BASE}/x/v3/fav/resource/infos?resources={urllib.parse.quote(res)}" f"&platform=web&folder_mid={cfg['mid']}&folder_id={mid}") r = get(url, ck) d = r.get("data") n = len(d) if isinstance(d, list) else "-" first = (d[0].get("title", "")[:18] if isinstance(d, list) and d else "") print(f" [{name:<14}] media={mid:<11} code={r.get('code')!s:<5} " f"返回={n!s:<3} msg={r.get('message')} {first}") time.sleep(1.2) print() if __name__ == "__main__": main()