From b9b0e7a0b9e9e6efd3a9d9fa9ba39ecbc2e6948a Mon Sep 17 00:00:00 2001 From: yzqzss Date: Sun, 9 Jul 2023 01:05:17 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20py3.10=20=E5=8F=8A=E4=BB=A5=E4=B8=8B?= =?UTF-8?q?=E7=9A=84=20cookiejar=20=E6=97=A0=E6=B3=95=E5=8A=A0=E8=BD=BD=20?= =?UTF-8?q?HTTP-Only=20cookie?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- biliarchiver/cli_tools/bili_archive_bvids.py | 37 +++++++++++--------- biliarchiver/utils/http_patch.py | 29 +++++++++++++++ 2 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 biliarchiver/utils/http_patch.py diff --git a/biliarchiver/cli_tools/bili_archive_bvids.py b/biliarchiver/cli_tools/bili_archive_bvids.py index acb2121..dffd521 100644 --- a/biliarchiver/cli_tools/bili_archive_bvids.py +++ b/biliarchiver/cli_tools/bili_archive_bvids.py @@ -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') diff --git a/biliarchiver/utils/http_patch.py b/biliarchiver/utils/http_patch.py new file mode 100644 index 0000000..b84889e --- /dev/null +++ b/biliarchiver/utils/http_patch.py @@ -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)