fix: py3.10 及以下的 cookiejar 无法加载 HTTP-Only cookie

This commit is contained in:
yzqzss 2023-07-09 01:05:17 +08:00
parent 2dff8d0201
commit b9b0e7a0b9
2 changed files with 50 additions and 16 deletions

View File

@ -2,7 +2,7 @@ import asyncio
import os
import argparse
from pathlib import Path
import time
import sys
from typing import Optional, Union
from internetarchive import get_item
@ -14,6 +14,7 @@ from bilix.sites.bilibili.downloader import DownloaderBilibili
from rich.console import Console
from httpx import AsyncClient, Client
from rich.traceback import install
from biliarchiver.utils.http_patch import HttpOnlyCookie_Handler
install()
from biliarchiver.utils.string import human_readable_upper_part_map
@ -130,6 +131,7 @@ def update_cookies_from_browser(client: AsyncClient, browser: str):
except AttributeError:
raise AttributeError(f"Invalid Browser {browser}")
def update_cookies_from_file(client: AsyncClient, cookies_path: Union[str, Path]):
if isinstance(cookies_path, Path):
cookies_path = cookies_path.expanduser()
@ -139,24 +141,27 @@ def update_cookies_from_file(client: AsyncClient, cookies_path: Union[str, Path]
raise TypeError(f'cookies_path: {type(cookies_path)}')
assert os.path.exists(cookies_path), f'cookies 文件不存在: {cookies_path}'
from http.cookiejar import MozillaCookieJar
cj = MozillaCookieJar()
cj.load(f'{cookies_path}', ignore_discard=True, ignore_expires=True)
loadded_cookies = 0
for cookie in cj:
# only load bilibili cookies
if 'bilibili' in cookie.domain:
assert cookie.value is not None
client.cookies.set(
cookie.name, cookie.value, domain=cookie.domain, path=cookie.path
)
loadded_cookies += 1
print(f'{cookies_path} 品尝了 {loadded_cookies} 块 cookies')
if loadded_cookies > 100:
print('吃了过多的 cookies可能导致 httpx.Client 怠工,响应非常缓慢')
assert client.cookies.get('SESSDATA') is not None, 'SESSDATA 不存在'
# print(f'SESS_DATA: {client.cookies.get("SESSDATA")}')
with HttpOnlyCookie_Handler(cookies_path):
cj.load(f'{cookies_path}', ignore_discard=True, ignore_expires=True)
loadded_cookies = 0
for cookie in cj:
# only load bilibili cookies
if 'bilibili' in cookie.domain:
assert cookie.value is not None
client.cookies.set(
cookie.name, cookie.value, domain=cookie.domain, path=cookie.path
)
loadded_cookies += 1
print(f'{cookies_path} 品尝了 {loadded_cookies} 块 cookies')
if loadded_cookies > 100:
print('吃了过多的 cookies可能导致 httpx.Client 怠工,响应非常缓慢')
assert client.cookies.get('SESSDATA') is not None, 'SESSDATA 不存在'
# print(f'SESS_DATA: {client.cookies.get("SESSDATA")}')
def is_login(cilent: Client) -> bool:
r = cilent.get('https://api.bilibili.com/x/member/web/account')

View File

@ -0,0 +1,29 @@
from pathlib import Path
import sys
from typing import Union
class HttpOnlyCookie_Handler:
'''
如果 python<=3.10.6 去除 HTTP-Only cookie
bpo-38976
'''
cookies_path: Union[str, Path]
cookies_raw_str: str
def __init__(self, cookies_path: Union[str, Path]):
self.cookies_path = cookies_path
def __enter__(self):
if sys.version_info < (3, 10, 6):
print('python<=3.9,去除 HTTP-Only cookie')
HTTPONLY_PREFIX = "#HttpOnly_"
with open(self.cookies_path, 'r', encoding='utf-8') as f:
self.cookies_raw_str = f.read()
cookies_new_str = self.cookies_raw_str.replace(HTTPONLY_PREFIX, '')
with open(self.cookies_path, 'w', encoding='utf-8') as f:
f.write(cookies_new_str)
def __exit__(self, exc_type, exc_value, traceback):
if sys.version_info < (3, 10, 6):
print('python<=3.9,恢复 HTTP-Only cookie')
with open(self.cookies_path, 'w', encoding='utf-8') as f:
f.write(self.cookies_raw_str)