diff --git a/README.md b/README.md index eb1c27ab..dbe72502 100644 --- a/README.md +++ b/README.md @@ -250,6 +250,7 @@ __Docker 最新版本由 [Sakuracio](https://github.com/Sakuracio) 提供__ * 修复图库内图片无法被连续删除的问题 [@pull/879](https://github.com/HibiKier/zhenxun_bot/pull/879) * 色图提供配置项`MAX_ONCE_NUM2FORWARD`:群聊中单次发送图片数量达到指定时使用合并转发 * 优化修复了商品修改命令 +* B站订阅UP动态改为详情页截图 ### 2022/6/28 diff --git a/plugins/bilibili_sub/data_source.py b/plugins/bilibili_sub/data_source.py index a902d0ff..e0757f9a 100755 --- a/plugins/bilibili_sub/data_source.py +++ b/plugins/bilibili_sub/data_source.py @@ -1,4 +1,6 @@ from bilireq.exceptions import ResponseCodeError +from nonebot.adapters.onebot.v11 import MessageSegment + from utils.manager import resources_manager from asyncio.exceptions import TimeoutError from .model import BilibiliSub @@ -8,7 +10,7 @@ from utils.message_builder import image from bilireq.user import get_user_info from bilireq import dynamic from .utils import get_videos -from typing import Optional +from typing import Optional, Tuple from configs.path_config import IMAGE_PATH from datetime import datetime from utils.browser import get_browser @@ -304,7 +306,7 @@ async def _get_season_status(id_) -> Optional[str]: async def get_user_dynamic( uid: int, local_user: BilibiliSub -) -> "Optional[MessageSegment], int": +) -> Tuple[Optional[MessageSegment], int]: """ 获取用户动态 :param uid: 用户uid @@ -317,14 +319,15 @@ async def get_user_dynamic( if dynamic_info.get("cards") and browser: dynamic_upload_time = dynamic_info["cards"][0]["desc"]["timestamp"] if local_user.dynamic_upload_time < dynamic_upload_time: - page = await browser.new_page() + context = await browser.new_context() + page = await context.new_page() try: await page.goto( f"https://space.bilibili.com/{local_user.uid}/dynamic", wait_until="networkidle", timeout=10000, ) - await page.set_viewport_size({"width": 2560, "height": 1080, "timeout": 10000*20}) # timeout: 200s + # await page.set_viewport_size({"width": 2560, "height": 1080, "timeout": 10000*20}) # timeout: 200s # 删除置顶 await page.evaluate( """ @@ -334,15 +337,30 @@ async def get_user_dynamic( } """ ) - card = page.locator(".bili-dyn-list__item").first + async with page.expect_popup() as popup_info: + await page.locator(".bili-rich-text__content").click() + details_page = await popup_info.value + await details_page.set_viewport_size( + {"width": 2560, "height": 1080, "timeout": 10000 * 20} + ) + await details_page.wait_for_selector(".panel-area") + await details_page.evaluate( + """ + xs = document.getElementById('internationalHeader'); + xs.remove(); + xs = document.getElementsByClassName('panel-area') + xs[0].remove(); + """ + ) + card = details_page.locator(".detail-card") await card.wait_for() - # 截图并保存 await card.screenshot( path=dynamic_path / f"{local_user.sub_id}_{dynamic_upload_time}.jpg", ) except Exception as e: logger.error(f"B站订阅:获取用户动态 发送错误 {type(e)}:{e}") finally: + await context.close() await page.close() return ( image( @@ -351,7 +369,7 @@ async def get_user_dynamic( ), dynamic_upload_time, ) - return None, None + return None, 0 class SubManager: diff --git a/update_info.json b/update_info.json index 21c5a2a2..f6245b00 100644 --- a/update_info.json +++ b/update_info.json @@ -10,7 +10,8 @@ "poetry.lock", "pyproject.toml", "resources/font", - "bot.py" + "resources/image/zhenxun", + "resources/image/other" ], "add_file": [], "delete_file": [] diff --git a/utils/browser.py b/utils/browser.py index 12f1d5d5..d602968d 100755 --- a/utils/browser.py +++ b/utils/browser.py @@ -2,14 +2,9 @@ import asyncio from typing import Optional from nonebot.log import logger from playwright.async_api import Browser, async_playwright -import nonebot -from nonebot import Driver from services.log import logger -driver: Driver = nonebot.get_driver() - - _browser: Optional[Browser] = None @@ -20,8 +15,8 @@ async def init(**kwargs) -> Optional[Browser]: _browser = await browser.chromium.launch(**kwargs) return _browser except Exception as e: - logger.warning(f"启动chromium发生错误 {type(e)}:{e}") - asyncio.get_event_loop().run_in_executor(None, install) + # logger.warning(f"启动chromium发生错误 {type(e)}:{e}") + await asyncio.get_event_loop().run_in_executor(None, install) _browser = await browser.chromium.launch(**kwargs) return None diff --git a/utils/http_utils.py b/utils/http_utils.py index e7550920..130e1ce1 100644 --- a/utils/http_utils.py +++ b/utils/http_utils.py @@ -6,7 +6,7 @@ from pathlib import Path from httpx import Response from asyncio.exceptions import TimeoutError from nonebot.adapters.onebot.v11 import MessageSegment -from playwright.async_api import Page +from playwright.async_api import Page, BrowserContext from .message_builder import image from httpx import ConnectTimeout from .browser import get_browser @@ -135,6 +135,7 @@ class AsyncHttpx: :param url: url :param path: 存储路径 :param params: params + :param verify: verify :param use_proxy: 使用代理 :param proxy: 指定代理 :param headers: 请求头 @@ -297,6 +298,19 @@ class AsyncPlaywright: return await browser.new_page(user_agent=user_agent, **kwargs) raise BrowserIsNone("获取Browser失败...") + @classmethod + async def new_context(cls, user_agent: Optional[str] = None, **kwargs) -> BrowserContext: + """ + 说明: + 获取一个新上下文 + 参数: + :param user_agent: 请求头 + """ + browser = await get_browser() + if browser: + return await browser.new_context(user_agent=user_agent, **kwargs) + raise BrowserIsNone("获取Browser失败...") + @classmethod async def goto( cls,