️ 试图提高截图速度

This commit is contained in:
2024-09-14 04:50:37 +08:00
parent d493ba5f0d
commit a206098805
2 changed files with 34 additions and 7 deletions

View File

@@ -1,12 +1,14 @@
import sys import sys
from collections.abc import Callable, Coroutine
from os import environ from os import environ
from platform import system from platform import system
from re import sub from re import sub
from typing import Any, ClassVar
from nonebot import get_driver from nonebot import get_driver
from nonebot.log import logger from nonebot.log import logger
from playwright.__main__ import main from playwright.__main__ import main
from playwright.async_api import Browser, async_playwright from playwright.async_api import Browser, BrowserContext, async_playwright
driver = get_driver() driver = get_driver()
@@ -27,6 +29,7 @@ class BrowserManager:
"""浏览器管理类""" """浏览器管理类"""
_browser: Browser | None = None _browser: Browser | None = None
_contexts: ClassVar[dict[str, BrowserContext]] = {}
@classmethod @classmethod
async def init_playwright(cls) -> None: async def init_playwright(cls) -> None:
@@ -72,7 +75,11 @@ class BrowserManager:
async def _start_browser(cls) -> Browser: async def _start_browser(cls) -> Browser:
"""启动浏览器实例""" """启动浏览器实例"""
playwright = await async_playwright().start() playwright = await async_playwright().start()
cls._browser = await playwright.firefox.launch() cls._browser = await playwright.firefox.launch(
firefox_user_prefs={
'network.http.max-persistent-connections-per-server': 64,
},
)
return cls._browser return cls._browser
@classmethod @classmethod
@@ -80,8 +87,26 @@ class BrowserManager:
"""获取浏览器实例""" """获取浏览器实例"""
return cls._browser or await cls._start_browser() return cls._browser or await cls._start_browser()
@classmethod
async def get_context(
cls, context_id: str = 'default', factory: Callable[[], Coroutine[Any, Any, BrowserContext]] | None = None
) -> BrowserContext:
"""获取浏览器上下文"""
return cls._contexts.setdefault(
context_id, await factory() if factory is not None else await (await cls.get_browser()).new_context()
)
@classmethod
async def del_context(cls, context_id: str) -> None:
"""删除浏览器上下文"""
if context_id in cls._contexts:
await cls._contexts[context_id].close()
del cls._contexts[context_id]
@classmethod @classmethod
async def close_browser(cls) -> None: async def close_browser(cls) -> None:
"""关闭浏览器实例""" """关闭浏览器实例"""
for i in cls._contexts.values():
await i.close()
if isinstance(cls._browser, Browser): if isinstance(cls._browser, Browser):
await cls._browser.close() await cls._browser.close()

View File

@@ -1,4 +1,4 @@
from playwright.async_api import TimeoutError, ViewportSize from playwright.async_api import BrowserContext, TimeoutError, ViewportSize
from ..config.config import config from ..config.config import config
from .browser import BrowserManager from .browser import BrowserManager
@@ -6,13 +6,15 @@ from .retry import retry
from .time_it import time_it from .time_it import time_it
async def context_factory() -> BrowserContext:
return await (await BrowserManager.get_browser()).new_context(device_scale_factor=config.tetris.screenshot_quality)
@retry(exception_type=TimeoutError, reply='截图失败, 重试中') @retry(exception_type=TimeoutError, reply='截图失败, 重试中')
@time_it @time_it
async def screenshot(url: str) -> bytes: async def screenshot(url: str) -> bytes:
browser = await BrowserManager.get_browser() context = await BrowserManager.get_context('screenshot', factory=context_factory)
async with ( async with await context.new_page() as page:
await browser.new_page(device_scale_factor=config.tetris.screenshot_quality) as page,
):
await page.goto(url) await page.goto(url)
size: ViewportSize = await page.evaluate(""" size: ViewportSize = await page.evaluate("""
() => { () => {