graiax-playwright


Namegraiax-playwright JSON
Version 0.4.1 PyPI version JSON
download
home_page
Summary适用于 Graia 的 Playwright 管理器
upload_time2023-12-18 14:46:04
maintainer
docs_urlNone
author
requires_python>=3.10
licenseMIT
keywords graia graiax launart playwright
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <div align="center">

# GraiaX Playwright

_适用于 Graia Project 的 Playwright 管理器_

[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)
[![License](https://img.shields.io/github/license/GraiaCommunity/graiax-playwright)](https://github.com/GraiaCommunity/graiax-playwright/blob/master/LICENSE)
[![pdm-managed](https://img.shields.io/badge/pdm-managed-blueviolet)](https://pdm.fming.dev)
[![PyPI](https://img.shields.io/pypi/v/graiax-playwright)](https://img.shields.io/pypi/v/graiax-playwright)

</div>

Graiax Playwright 使用 [launart](https://github.com/GraiaProject/launart) 作为启动管理器,
适用于 [Ariadne](https://github.com/GraiaProject/Ariadne) 及 [Avilla](https://github.com/GraiaProject/Avilla)。

通过 GraiaX Playwright 你可以轻松地在 Ariadne / Avilla 启动的时候同时启动一个
Playwright,并在其退出的时候自动关闭 Playwright。

> 需要注意的是,Playwright 将会在运行期间保持后台常驻,  
> 但由于并未开启任何页面,其内存占用量不是非常大(但也是可观的)。

## 安装

`pdm add graiax-playwright` 或 `poetry add graiax-playwright`。

> 我们强烈建议使用包管理器或虚拟环境

## 开始使用

以下教程以配合 Launart 使用为例。

### 机器人入口文件

```python
from creart import create
from launart import Launart
from graia.ariadne.app import Ariadne
from graiax.playwright import PlaywrightService

launart = create(Launart)
launart.add_component(PlaywrightService("chromium")) # 默认值为 chromium
launart.add_component(PlaywrightService("chromium", user_data_dir="./browser_data"))  # 与上一行二选一,该方式使用 Persistent Context
...

launart.launch_blocking()
```

### 配合 Graia Saya 使用

```python
from creart import create
from launart import Launart
from graia.ariadne.util.saya import listen
from graiax.playwright import PlaywrightService


@listen(...)
async def function(app: Ariadne):
    launart = create(Launart)
    pw_service = launart.get_component(PlaywrightService)

    async with pw_service.page(  # 此 API 启用了自动上下文管理
        viewport={"width": 800, "height": 10},
        device_scale_factor=1.5,
    ) as page:
        await page.set_content("Hello World!")
        img = await page.screenshot(type="jpeg", quality=80, full_page=True, scale="device")
    ...
```

### 高级用法之一

上面配合 Saya 使用的例子展示了创建一个页面的例子,但该页面默认与其他页面互相**隔离**(例如 cookie
等),假如我们需要一个与其他页面**隔离**的新页面,那么我们可以使用
`page(use_global_context=False)` 在创建页面时使用一个新的上下文,如下所示:

> [!NOTE]  
> 该种用法中的新上下文,仍受到 Playwright 启动参数的影响
>
> 如果你传入了例如 `viewport` 之类的只有新创建上下文或者新页面才支持的参数时,则会忽略
> `use_global_context` 参数。此时若 `without_new_context`
> 为 `True`(默认行为),则将会直接使用浏览器实例创建新页面。
> 反之则会先创建新上下文再用新的上下文创建新页面,但是结束时新的页面和上下文都会被关闭。
>
> 更多信息详见:<https://playwright.dev/python/docs/browser-contexts>

```python
@listen(...)
async def function(app: Ariadne):
    launart = create(Launart)
    pw_service = launart.get_component(PlaywrightService)
    async with pw_service.page(use_global_context=False) as page:  # 此 API 启用了自动上下文管理
        await page.set_content("Hello World!")
        img = await page.screenshot(type="jpeg", quality=80, full_page=True, scale="device")
    ...
```

### 高级用法之二

上面配合 Saya 使用的例子展示了为**单个页面**设置 viewport 的功能,自 GraiaX Playwright `v0.3.1`
版本起,可以在创建 PlaywrightService 时为全局的 Browser Context 指定 viewport,然后在截图时使用全局
Browser Context 截图,如下所示:

**机器人入口文件:**

```python
launart.add_service(PlaywrightService("chromium"))
```

**Saya 模块中:**

```python
from graiax.playwright import PlaywrightService


@listen(...)
async def function(app: Ariadne):
    launart = create(Launart)
    pw_service = manager.get_component(PlaywrightService)
    async with pw_service.context(...) as context:  # 此 API 启用了自动上下文管理
        page = context.new_page()
        try:
            await page.set_content("Hello World!")
            img = await page.screenshot(type="jpeg", quality=80, full_page=True, scale='device')
        finally:
            page.stop()
    ...
```

### 高级用法之三

通过依赖注入来获取 `PlaywrightService`,前面的代码中获取 `PlaywrightService` 都需要通过 Launart
的 `get_component()` 方法,你也可以通过自定义一个 BCC 的 `Dispatcher` 来实现依赖注入。

编写一个 `Dispatcher`:

```python
from graia.broadcast.entities.dispatcher import BaseDispatcher
from graia.broadcast.interfaces.dispatcher import DispatcherInterface

class CustomDispatcher(BaseDispatcher):
    @classmethod
    async def catch(cls, interface: DispatcherInterface):
        with contextlib.suppress(TypeError):
            if generic_isinstance(interface.event, Service):
                manager = Launart.current()
                return manager.get_component(interface.annotation)
```

在启动 Launart 之前获取一个 BCC 实例并对其应用这个 `Dispatcher`:

```python
from creart import it
from graia.broadcast import Broadcast

bcc = it(Broadcast)
bcc.finale_dispatchers.append(RedbotDispatcher)

...

launart.launch_blocking() # 或者是 avilla.launch()
```

之后用起来就很简单了,你可以对比一下有什么不同:

```python
from graiax.playwright import PlaywrightService

@listen(...)
async def function(app: Ariadne, pw_service: PlaywrightService):
    async with pw_service.page(...) as page:
        ...
```

## 许可证

本项目使用 [`MIT`](./LICENSE) 许可证进行许可。

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "graiax-playwright",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": "",
    "keywords": "graia graiax launart playwright",
    "author": "",
    "author_email": "BlueGlassBlock <blueglassblock@outlook.com>, I Love Study <1450069615@qq.com>, Redlnn <w731347477@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/0f/d2/f757a12780a8fafd100ad740069f9690419647756db1cdef59962e70bfb1/graiax_playwright-0.4.1.tar.gz",
    "platform": null,
    "description": "<div align=\"center\">\n\n# GraiaX Playwright\n\n_\u9002\u7528\u4e8e Graia Project \u7684 Playwright \u7ba1\u7406\u5668_\n\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n[![License](https://img.shields.io/github/license/GraiaCommunity/graiax-playwright)](https://github.com/GraiaCommunity/graiax-playwright/blob/master/LICENSE)\n[![pdm-managed](https://img.shields.io/badge/pdm-managed-blueviolet)](https://pdm.fming.dev)\n[![PyPI](https://img.shields.io/pypi/v/graiax-playwright)](https://img.shields.io/pypi/v/graiax-playwright)\n\n</div>\n\nGraiax Playwright \u4f7f\u7528 [launart](https://github.com/GraiaProject/launart) \u4f5c\u4e3a\u542f\u52a8\u7ba1\u7406\u5668\uff0c\n\u9002\u7528\u4e8e [Ariadne](https://github.com/GraiaProject/Ariadne) \u53ca [Avilla](https://github.com/GraiaProject/Avilla)\u3002\n\n\u901a\u8fc7 GraiaX Playwright \u4f60\u53ef\u4ee5\u8f7b\u677e\u5730\u5728 Ariadne / Avilla \u542f\u52a8\u7684\u65f6\u5019\u540c\u65f6\u542f\u52a8\u4e00\u4e2a\nPlaywright\uff0c\u5e76\u5728\u5176\u9000\u51fa\u7684\u65f6\u5019\u81ea\u52a8\u5173\u95ed Playwright\u3002\n\n> \u9700\u8981\u6ce8\u610f\u7684\u662f\uff0cPlaywright \u5c06\u4f1a\u5728\u8fd0\u884c\u671f\u95f4\u4fdd\u6301\u540e\u53f0\u5e38\u9a7b\uff0c  \n> \u4f46\u7531\u4e8e\u5e76\u672a\u5f00\u542f\u4efb\u4f55\u9875\u9762\uff0c\u5176\u5185\u5b58\u5360\u7528\u91cf\u4e0d\u662f\u975e\u5e38\u5927\uff08\u4f46\u4e5f\u662f\u53ef\u89c2\u7684\uff09\u3002\n\n## \u5b89\u88c5\n\n`pdm add graiax-playwright` \u6216 `poetry add graiax-playwright`\u3002\n\n> \u6211\u4eec\u5f3a\u70c8\u5efa\u8bae\u4f7f\u7528\u5305\u7ba1\u7406\u5668\u6216\u865a\u62df\u73af\u5883\n\n## \u5f00\u59cb\u4f7f\u7528\n\n\u4ee5\u4e0b\u6559\u7a0b\u4ee5\u914d\u5408 Launart \u4f7f\u7528\u4e3a\u4f8b\u3002\n\n### \u673a\u5668\u4eba\u5165\u53e3\u6587\u4ef6\n\n```python\nfrom creart import create\nfrom launart import Launart\nfrom graia.ariadne.app import Ariadne\nfrom graiax.playwright import PlaywrightService\n\nlaunart = create(Launart)\nlaunart.add_component(PlaywrightService(\"chromium\")) # \u9ed8\u8ba4\u503c\u4e3a chromium\nlaunart.add_component(PlaywrightService(\"chromium\"\uff0c user_data_dir=\"./browser_data\"))  # \u4e0e\u4e0a\u4e00\u884c\u4e8c\u9009\u4e00\uff0c\u8be5\u65b9\u5f0f\u4f7f\u7528 Persistent Context\n...\n\nlaunart.launch_blocking()\n```\n\n### \u914d\u5408 Graia Saya \u4f7f\u7528\n\n```python\nfrom creart import create\nfrom launart import Launart\nfrom graia.ariadne.util.saya import listen\nfrom graiax.playwright import PlaywrightService\n\n\n@listen(...)\nasync def function(app: Ariadne):\n    launart = create(Launart)\n    pw_service = launart.get_component(PlaywrightService)\n\n    async with pw_service.page(  # \u6b64 API \u542f\u7528\u4e86\u81ea\u52a8\u4e0a\u4e0b\u6587\u7ba1\u7406\n        viewport={\"width\": 800, \"height\": 10},\n        device_scale_factor=1.5,\n    ) as page:\n        await page.set_content(\"Hello World!\")\n        img = await page.screenshot(type=\"jpeg\", quality=80, full_page=True, scale=\"device\")\n    ...\n```\n\n### \u9ad8\u7ea7\u7528\u6cd5\u4e4b\u4e00\n\n\u4e0a\u9762\u914d\u5408 Saya \u4f7f\u7528\u7684\u4f8b\u5b50\u5c55\u793a\u4e86\u521b\u5efa\u4e00\u4e2a\u9875\u9762\u7684\u4f8b\u5b50\uff0c\u4f46\u8be5\u9875\u9762\u9ed8\u8ba4\u4e0e\u5176\u4ed6\u9875\u9762\u4e92\u76f8**\u9694\u79bb**\uff08\u4f8b\u5982 cookie\n\u7b49\uff09\uff0c\u5047\u5982\u6211\u4eec\u9700\u8981\u4e00\u4e2a\u4e0e\u5176\u4ed6\u9875\u9762**\u9694\u79bb**\u7684\u65b0\u9875\u9762\uff0c\u90a3\u4e48\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528\n`page(use_global_context=False)` \u5728\u521b\u5efa\u9875\u9762\u65f6\u4f7f\u7528\u4e00\u4e2a\u65b0\u7684\u4e0a\u4e0b\u6587\uff0c\u5982\u4e0b\u6240\u793a\uff1a\n\n> [!NOTE]  \n> \u8be5\u79cd\u7528\u6cd5\u4e2d\u7684\u65b0\u4e0a\u4e0b\u6587\uff0c\u4ecd\u53d7\u5230 Playwright \u542f\u52a8\u53c2\u6570\u7684\u5f71\u54cd\n>\n> \u5982\u679c\u4f60\u4f20\u5165\u4e86\u4f8b\u5982 `viewport` \u4e4b\u7c7b\u7684\u53ea\u6709\u65b0\u521b\u5efa\u4e0a\u4e0b\u6587\u6216\u8005\u65b0\u9875\u9762\u624d\u652f\u6301\u7684\u53c2\u6570\u65f6\uff0c\u5219\u4f1a\u5ffd\u7565\n> `use_global_context` \u53c2\u6570\u3002\u6b64\u65f6\u82e5 `without_new_context`\n> \u4e3a `True`\uff08\u9ed8\u8ba4\u884c\u4e3a\uff09\uff0c\u5219\u5c06\u4f1a\u76f4\u63a5\u4f7f\u7528\u6d4f\u89c8\u5668\u5b9e\u4f8b\u521b\u5efa\u65b0\u9875\u9762\u3002\n> \u53cd\u4e4b\u5219\u4f1a\u5148\u521b\u5efa\u65b0\u4e0a\u4e0b\u6587\u518d\u7528\u65b0\u7684\u4e0a\u4e0b\u6587\u521b\u5efa\u65b0\u9875\u9762\uff0c\u4f46\u662f\u7ed3\u675f\u65f6\u65b0\u7684\u9875\u9762\u548c\u4e0a\u4e0b\u6587\u90fd\u4f1a\u88ab\u5173\u95ed\u3002\n>\n> \u66f4\u591a\u4fe1\u606f\u8be6\u89c1\uff1a<https://playwright.dev/python/docs/browser-contexts>\n\n```python\n@listen(...)\nasync def function(app: Ariadne):\n    launart = create(Launart)\n    pw_service = launart.get_component(PlaywrightService)\n    async with pw_service.page(use_global_context=False) as page:  # \u6b64 API \u542f\u7528\u4e86\u81ea\u52a8\u4e0a\u4e0b\u6587\u7ba1\u7406\n        await page.set_content(\"Hello World!\")\n        img = await page.screenshot(type=\"jpeg\", quality=80, full_page=True, scale=\"device\")\n    ...\n```\n\n### \u9ad8\u7ea7\u7528\u6cd5\u4e4b\u4e8c\n\n\u4e0a\u9762\u914d\u5408 Saya \u4f7f\u7528\u7684\u4f8b\u5b50\u5c55\u793a\u4e86\u4e3a**\u5355\u4e2a\u9875\u9762**\u8bbe\u7f6e viewport \u7684\u529f\u80fd\uff0c\u81ea GraiaX Playwright `v0.3.1`\n\u7248\u672c\u8d77\uff0c\u53ef\u4ee5\u5728\u521b\u5efa PlaywrightService \u65f6\u4e3a\u5168\u5c40\u7684 Browser Context \u6307\u5b9a viewport\uff0c\u7136\u540e\u5728\u622a\u56fe\u65f6\u4f7f\u7528\u5168\u5c40\nBrowser Context \u622a\u56fe\uff0c\u5982\u4e0b\u6240\u793a\uff1a\n\n**\u673a\u5668\u4eba\u5165\u53e3\u6587\u4ef6\uff1a**\n\n```python\nlaunart.add_service(PlaywrightService(\"chromium\"))\n```\n\n**Saya \u6a21\u5757\u4e2d\uff1a**\n\n```python\nfrom graiax.playwright import PlaywrightService\n\n\n@listen(...)\nasync def function(app: Ariadne):\n    launart = create(Launart)\n    pw_service = manager.get_component(PlaywrightService)\n    async with pw_service.context(...) as context:  # \u6b64 API \u542f\u7528\u4e86\u81ea\u52a8\u4e0a\u4e0b\u6587\u7ba1\u7406\n        page = context.new_page()\n        try:\n            await page.set_content(\"Hello World!\")\n            img = await page.screenshot(type=\"jpeg\", quality=80, full_page=True, scale='device')\n        finally:\n            page.stop()\n    ...\n```\n\n### \u9ad8\u7ea7\u7528\u6cd5\u4e4b\u4e09\n\n\u901a\u8fc7\u4f9d\u8d56\u6ce8\u5165\u6765\u83b7\u53d6 `PlaywrightService`\uff0c\u524d\u9762\u7684\u4ee3\u7801\u4e2d\u83b7\u53d6 `PlaywrightService` \u90fd\u9700\u8981\u901a\u8fc7 Launart\n\u7684 `get_component()` \u65b9\u6cd5\uff0c\u4f60\u4e5f\u53ef\u4ee5\u901a\u8fc7\u81ea\u5b9a\u4e49\u4e00\u4e2a BCC \u7684 `Dispatcher` \u6765\u5b9e\u73b0\u4f9d\u8d56\u6ce8\u5165\u3002\n\n\u7f16\u5199\u4e00\u4e2a `Dispatcher`\uff1a\n\n```python\nfrom graia.broadcast.entities.dispatcher import BaseDispatcher\nfrom graia.broadcast.interfaces.dispatcher import DispatcherInterface\n\nclass CustomDispatcher(BaseDispatcher):\n    @classmethod\n    async def catch(cls, interface: DispatcherInterface):\n        with contextlib.suppress(TypeError):\n            if generic_isinstance(interface.event, Service):\n                manager = Launart.current()\n                return manager.get_component(interface.annotation)\n```\n\n\u5728\u542f\u52a8 Launart \u4e4b\u524d\u83b7\u53d6\u4e00\u4e2a BCC \u5b9e\u4f8b\u5e76\u5bf9\u5176\u5e94\u7528\u8fd9\u4e2a `Dispatcher`\uff1a\n\n```python\nfrom creart import it\nfrom graia.broadcast import Broadcast\n\nbcc = it(Broadcast)\nbcc.finale_dispatchers.append(RedbotDispatcher)\n\n...\n\nlaunart.launch_blocking() # \u6216\u8005\u662f avilla.launch()\n```\n\n\u4e4b\u540e\u7528\u8d77\u6765\u5c31\u5f88\u7b80\u5355\u4e86\uff0c\u4f60\u53ef\u4ee5\u5bf9\u6bd4\u4e00\u4e0b\u6709\u4ec0\u4e48\u4e0d\u540c\uff1a\n\n```python\nfrom graiax.playwright import PlaywrightService\n\n@listen(...)\nasync def function(app: Ariadne, pw_service: PlaywrightService):\n    async with pw_service.page(...) as page:\n        ...\n```\n\n## \u8bb8\u53ef\u8bc1\n\n\u672c\u9879\u76ee\u4f7f\u7528 [`MIT`](./LICENSE) \u8bb8\u53ef\u8bc1\u8fdb\u884c\u8bb8\u53ef\u3002\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "\u9002\u7528\u4e8e Graia \u7684 Playwright \u7ba1\u7406\u5668",
    "version": "0.4.1",
    "project_urls": {
        "Repository": "https://github.com/GraiaCommunity/graiax-playwright"
    },
    "split_keywords": [
        "graia",
        "graiax",
        "launart",
        "playwright"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "de79111aacedd8b98947d564c926b0692314943390e4d954e270070e30904655",
                "md5": "45adc4e932cc57c17211fa82352b8205",
                "sha256": "4d44a5d2a8d5755e5b1f037150d3ac6fd9ef26f5fe4fe7f61811c1ea544f8b81"
            },
            "downloads": -1,
            "filename": "graiax_playwright-0.4.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "45adc4e932cc57c17211fa82352b8205",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 14214,
            "upload_time": "2023-12-18T14:46:02",
            "upload_time_iso_8601": "2023-12-18T14:46:02.693429Z",
            "url": "https://files.pythonhosted.org/packages/de/79/111aacedd8b98947d564c926b0692314943390e4d954e270070e30904655/graiax_playwright-0.4.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0fd2f757a12780a8fafd100ad740069f9690419647756db1cdef59962e70bfb1",
                "md5": "f59d2cea752cf8e7a56bbba2d2144398",
                "sha256": "d84b2a3491bde31e8adcb8d2b86680d81a1a8d9e5d33467553b1ccf487318f02"
            },
            "downloads": -1,
            "filename": "graiax_playwright-0.4.1.tar.gz",
            "has_sig": false,
            "md5_digest": "f59d2cea752cf8e7a56bbba2d2144398",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 12763,
            "upload_time": "2023-12-18T14:46:04",
            "upload_time_iso_8601": "2023-12-18T14:46:04.693167Z",
            "url": "https://files.pythonhosted.org/packages/0f/d2/f757a12780a8fafd100ad740069f9690419647756db1cdef59962e70bfb1/graiax_playwright-0.4.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-18 14:46:04",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "GraiaCommunity",
    "github_project": "graiax-playwright",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "graiax-playwright"
}
        
Elapsed time: 0.16934s