113 lines
3.6 KiB
Python
113 lines
3.6 KiB
Python
# 从根目录 cookies.txt 加载并注入 cookies(支持 Netscape 与 nodriver 原生格式)
|
||
|
||
from pathlib import Path
|
||
|
||
# 项目根目录(本文件所在目录的父目录即 audcf)
|
||
ROOT_DIR = Path(__file__).resolve().parent
|
||
COOKIES_FILE = ROOT_DIR / "cookies.txt"
|
||
|
||
|
||
def get_cookies_path() -> Path:
|
||
return COOKIES_FILE
|
||
|
||
|
||
def cookies_file_exists() -> bool:
|
||
return COOKIES_FILE.is_file()
|
||
|
||
|
||
def is_netscape_format(path: Path) -> bool:
|
||
"""根据首行判断是否为 Netscape cookies.txt 格式。"""
|
||
if not path.is_file():
|
||
return False
|
||
try:
|
||
with open(path, "r", encoding="utf-8", errors="ignore") as f:
|
||
first = f.readline().strip()
|
||
return first.startswith("# Netscape") or first.startswith("# HTTP Cookie File")
|
||
except Exception:
|
||
return False
|
||
|
||
|
||
def parse_netscape_cookies(path: Path) -> list[dict]:
|
||
"""
|
||
解析 Netscape 格式 cookies.txt(含 Cookie-Editor 等导出的多行注释)。
|
||
每行(非注释):domain, subdomain, path, secure, expires, name, value(制表符分隔;value 可含制表符故用 maxsplit=6)
|
||
返回字典列表供转为 CookieParam。
|
||
"""
|
||
cookies = []
|
||
with open(path, "r", encoding="utf-8", errors="ignore") as f:
|
||
for line in f:
|
||
line = line.strip()
|
||
if not line or line.startswith("#"):
|
||
continue
|
||
parts = line.split("\t", 6)
|
||
if len(parts) < 7:
|
||
continue
|
||
domain, _subdomain, path_val, secure_val, expires_str, name, value = parts
|
||
secure = secure_val.upper() == "TRUE"
|
||
try:
|
||
expires = float(expires_str) if expires_str and expires_str != "0" else None
|
||
except ValueError:
|
||
expires = None
|
||
cookies.append({
|
||
"name": name,
|
||
"value": value,
|
||
"domain": domain,
|
||
"path": path_val or "/",
|
||
"expires": expires,
|
||
"http_only": False,
|
||
"secure": secure,
|
||
"same_site": "Lax",
|
||
})
|
||
return cookies
|
||
|
||
|
||
async def load_cookies_nodriver_native(browser, path: Path) -> bool:
|
||
"""
|
||
使用 nodriver 原生格式加载 cookies(browser.cookies.load)。
|
||
成功返回 True,失败返回 False。
|
||
"""
|
||
try:
|
||
await browser.cookies.load(file=str(path))
|
||
return True
|
||
except Exception:
|
||
return False
|
||
|
||
|
||
def _dict_to_cookie_param(d: dict):
|
||
"""将解析后的 cookie 字典转为 nodriver CDP 所需的 CookieParam。"""
|
||
from nodriver.cdp import network
|
||
expires = d.get("expires")
|
||
if expires is not None:
|
||
expires = network.TimeSinceEpoch(expires)
|
||
same_site = d.get("same_site")
|
||
if same_site:
|
||
same_site = network.CookieSameSite(same_site)
|
||
return network.CookieParam(
|
||
name=d["name"],
|
||
value=d["value"],
|
||
domain=d.get("domain"),
|
||
path=d.get("path") or "/",
|
||
secure=d.get("secure"),
|
||
http_only=d.get("http_only"),
|
||
same_site=same_site,
|
||
expires=expires,
|
||
)
|
||
|
||
|
||
async def inject_netscape_cookies(tab, path: Path) -> bool:
|
||
"""
|
||
解析 Netscape 格式的 cookies.txt 并通过 CDP 注入到当前 tab。
|
||
应在已打开目标域页面后调用。
|
||
成功返回 True,失败返回 False。
|
||
"""
|
||
try:
|
||
from nodriver import cdp
|
||
cookies_list = parse_netscape_cookies(path)
|
||
if not cookies_list:
|
||
return True
|
||
cookies_param = [_dict_to_cookie_param(d) for d in cookies_list]
|
||
await tab.send(cdp.storage.set_cookies(cookies=cookies_param))
|
||
return True
|
||
except Exception:
|
||
return False
|