Code Monkey home page Code Monkey logo

koishi-plugin-puppeteer's Introduction

koishi-plugin-puppeteer

npm

浏览器 API 服务,可用于网页截图等。

注意:为了正常使用这个插件,你首先需要确保你的电脑上已经安装有 Chromium。同时,我们建议你保持 Chromium 和本插件的更新,因为版本不匹配可能会导致本插件无法正常使用。

类:Puppeteer

可以通过 ctx.puppeteer 访问。

puppeteer.launch()

  • 返回值: Promise<void>

启动并连接浏览器。

puppeteer.close()

  • 返回值: Promise<void>

关闭浏览器并取消连接。

puppeteer.page()

  • 返回值: Promise<Page>

创建一个新页面。

puppeteer.render(content, callback?)

  • content: string 要渲染的 HTML
  • callback: (page, next) => Promise<string> 回调函数
    • page: Page 页面实例
    • next: (handle: ElementHandle) => Promise<string> 渲染函数
  • 返回值: string

渲染一个 HTML 页面。

koishi-plugin-puppeteer's People

Contributors

anillc avatar h4m5ter avatar idranme avatar lipraty avatar maxoyed avatar seidko avatar shigma avatar srk24 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

koishi-plugin-puppeteer's Issues

Bug: 使用 html 组件没法正常加载本地文件

这是失败的例子:

image

tmpHtml 里面使用了css和图片,都是绝对路径

代码:

return await ctx.puppeteer.render(tmpHtml)

这是我用自己写的puppeteer写的,成功的例子

image

代码

/**
   * `chromium` 截图
   * @param data 模板参数
   * @param data.tplFile 模板路径,必传
   * @param data.saveId  生成html名称,为空name代替
   * @param data.imgType  screenshot参数,生成图片类型:jpeg,png
   * @param data.quality  screenshot参数,图片质量 0-100,jpeg是可传,默认90
   * @param data.omitBackground  screenshot参数,隐藏默认的白色背景,背景透明。默认不透明
   * @param data.path   screenshot参数,截图保存路径。截图图片类型将从文件扩展名推断出来。如果是相对路径,则从当前路径解析。如果没有指定路径,图片将不会保存到硬盘。
   * @return oicq img
   */
  async screenshot (name, data = {}) {
    if (!await this.browserInit()) {
      return false
    }

    let savePath = this.dealTpl(name, data)
    if (!savePath) return false

    let buff = ''
    let start = Date.now()

    this.shoting.push(name)

    try {
      const page = await this.browser.newPage()
      await page.goto(`file://${_path}${lodash.trim(savePath, '.')}`, data.pageGotoParams || {})
      let body = await page.$('#container') || await page.$('body')

      let randData = {
        // encoding: 'base64',
        type: data.imgType || 'jpeg',
        omitBackground: data.omitBackground || false,
        quality: data.quality || 90,
        path: data.path || ''
      }

      if (data.imgType == 'png') delete randData.quality

      buff = await body.screenshot(randData)

      page.close().catch((err) => logger.error(err))
    } catch (error) {
      logger.error(`图片生成失败:${name}:${error}`)
      /** 关闭浏览器 */
      if (this.browser) {
        await this.browser.close().catch((err) => logger.error(err))
      }
      this.browser = false
      buff = ''
      return false
    }

    this.shoting.pop()

    if (!buff) {
      logger.error(`图片生成为空:${name}`)
      return false
    }

    this.renderNum++

    /** 计算图片大小 */
    let kb = (buff.length / 1024).toFixed(2) + 'kb'

    logger.info(`[图片生成][${name}][${this.renderNum}次] ${kb} ${`${Date.now() - start}ms`}`)

    this.restart()

    return segment.image(buff)
  }
···

### 使用环境:
操作系统: WINDOWS 10 
Node version: v16.15.1
puppeteer version: 3.0.2
koishi version: 4.10.3

Feature(pptr): 让 Puppeteer 尊重 Koishi 全局代理设置

目前 pptr 是没有跟随 Koishi 全局代理的设置:

this.browser = await puppeteer.launch({
...this.config,
executablePath,
})

希望尊重 Koishi 全局代理设置(

想的一个笨笨方法:

//add proxyAgent
if(ctx.root.config.request.proxyAgent){
   this.config.args.push([`--proxy-server=${ctx.root.config.request.proxyAgent}`])
}
this.browser = await puppeteer.launch({ 
   ...this.config, 
   executablePath, 
 }) 

Bug: puppeteer未正常运行

Describe the bug

比如插件商店里面的下棋的插件chess 按理说棋盘是以图片的形式发出来的,但实际上发的字符

Steps to reproduce

直接在插件里面安装puppeteer,并不做任何配置直接启用插件

Expected behavior

下棋的插件chess 应该是正确的发送图片(在使用v3koishi时成功过,但后来也忘记怎么操作了,但确实要自己手动的安装chrome的一个模块,
或许可以在写这个插件的是否自动检测,没有的进行安装一个?

在自定义那边,设置了指定文件也失败了
https://commondatastorage.googleapis.com/chromium-browser-snapshots/Linux_x64/982053/chrome-linux.zip

2022-04-27 13:02:14 [W] ndefined;1mapp Error: Failed to launch the browser process!
                        [0427/130214.085519:FATAL:zygote_host_impl_linux.cc(117)] No usable sandbox! Update your kernel or see https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md for more information on developing with the SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox.
                        #0 0x5564dbb87b89 base::debug::CollectStackTrace()
                        koishijs/koishi#1 0x5564dbaec433 base::debug::StackTrace::StackTrace()
                        koishijs/koishi#2 0x5564dbaff330 logging::LogMessage::~LogMessage()
                        koishijs/koishi#3 0x5564d9ae499b content::ZygoteHostImpl::Init()
                        koishijs/koishi#4 0x5564db695372 content::ContentMainRunnerImpl::Initialize()
                        koishijs/koishi#5 0x5564db693439 content::RunContentProcess()
                        koishijs/koishi#6 0x5564db69358e content::ContentMain()
                        koishijs/koishi#7 0x5564db6eed7a headless::(anonymous namespace)::RunContentMain()
                        koishijs/koishi#8 0x5564db6eea85 headless::HeadlessShellMain()
                        koishijs/koishi#9 0x5564d81523e8 ChromeMain
                        koishijs/koishi#10 0x7ff612bb8555 __libc_start_main
                        koishijs/koishi#11 0x5564d815222a _start
                        
                        
                        
                        TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
                        
                            at onClose (/koishi地址/node_modules/puppeteer-core/lib/cjs/puppeteer/node/BrowserRunner.js:241:20)
                            at Interface.<anonymous> (/koishi地址/node_modules/puppeteer-core/lib/cjs/puppeteer/node/BrowserRunner.js:231:68)
                            at Interface.emit (events.js:412:35)
                            at Interface.close (readline.js:530:8)
                            at Socket.onend (readline.js:254:10)
                            at Socket.emit (events.js:412:35)
                            at endReadableNT (internal/streams/readable.js:1334:12)
                            at processTicksAndRejections (internal/process/task_queues.js:82:21)

Screenshots

2022-04-27 12:51:21 [W] ndefined;1mapp TimeoutError: Timed out after 30000 ms while trying to connect to the browser! Only Chrome at revision r982053 is guaranteed to work.
                            at Timeout.onTimeout (/koishi地址/node_modules/puppeteer-core/lib/cjs/puppeteer/node/BrowserRunner.js:252:20)
                            at listOnTimeout (internal/timers.js:557:17)
                            at processTimers (internal/timers.js:500:7)

image

Versions

  • OS: CentOS 7.9.2009 x86_64
  • Platform: onebot
  • Node version: v14.19.0
  • Koishi version: 4.6.1

Additional context

No response

Docs: clarify not to use chrome installed by snap on Linux

The chrome browser that we are using can be installed by the snap, which is popular in these years and is the default package manager on Ubuntu Desktop. But the namespace mechanisms limits many allowances that causes the failure invoking from the puppeteer plugin of Koishi.

Therefore, we should clarify the disadvantages of using snap to install the chrome with the puppeteer plugin and suggest some alternatives methods.

Bug: TypeError: Cannot read properties of undefined (reading 'replace')

在使用 jsxsvg 内部的 text 标签会报错

<svg viewBox="0 0 100 100">
  <circle
    cx="50"
    cy="50"
    r="50"
    fill="none"
    stroke="#ccc"
    strokeWidth="10"
  />
  <circle
    cx="50"
    cy="50"
    r="50"
    fill="none"
    stroke="#f00"
    strokeWidth="10"
    strokeDasharray={2 * Math.PI * 50}
    strokeDashoffset={2 * Math.PI * 50 * (1 - 0.8)}
    transform="rotate(-90, 50, 50)"
  />
  <text
    x="50"
    y="50"
    textAnchor="middle"
    dominantBaseline="middle"
    fontSize="20"
    fill="#000"
  >
    {`${Math.floor(0.8 * 100)}%`}
  </text>
</svg>

Bug: Console Market 无法安装 puppeteer

Describe the bug

image
安装 github 插件告诉我pptr已安装
image
紧接着去搜索 pptr 告诉我未安装 点进去又是已安装
image
插件配置也找不到 pptr
image
但是通过 yarn 可以发现其实是安装了 pptr 的

删去 node_modules 加以多次重启后解决

Steps to reproduce

  1. 润一个新的 koishi-pttr docker
  2. 安装 github 插件 ( 可能非必须 )
  3. 去看 pptr 插件是否安装

Expected behavior

显示 pptr 已安装

Screenshots

https://pastebin.com/ca1nYhr0

Versions

System:
    OS: Linux 5.4 Alpine Linux
    CPU: (8) x64 Intel(R) Xeon(R) Gold 6133 CPU @ 2.50GHz
    GPU: Tesla V100-SXM2-32GB
    RAM: 22286MiB / 39359MiB
Binaries:
    Node: 18.13.0
    Yarn: 1.22.19

Koishi:
    Core: 4.11.2
    Console: 5.1.10

Additional context

此问题为尝试复现 koishijs/koishi-plugin-github#22 时出现的
可以顺便看看吗


edit: 转移 log

Feature: 希望koishi-plugin-puppeteer能修改渲染出的图片的格式,或者能压缩一下图片大小

Describe the problem related to the feature request

我用一张140kb的背景ctx.puppeteer.render()渲染后,图片的大小来到了2.6mb,图片质量没有提高,但响应时间大大增加了

Describe the solution you'd like

在图片质量不重要时,能不能增加某些可选参数降低一下图片的大小?

Describe alternatives you've considered

No response

Additional context

No response

Feature: Connect to Existing Browser Instance

Summary 简介

Since puppeteer supports connect to an existing browser instance rather than launching a new one, also it would ease the configuration for users. It would be great if the puppeteer plugin supported this feature as well.

由于 puppeteer 支持 connect 到一个现有的浏览器实例,而不是启动一个新的,而且这样会方便用户配置。如果 puppeteer 插件也能支持这个功能会很好。

Possible Approach 可能的路线

  • Add a new config to choose whether to use Launch or Connect for handling a browser instance.
  • When the user selects Connect, show a text input box for entering the existing browser URI.
  • And then the plugin would connect to it when it started to provide the service.
  • 添加一个新的选项用于处理浏览器实例,使用 LaunchConnect
  • 如果用户选择 Connect,显示一个文本输入框使其输入现有的浏览器的 URI。
  • 然后插件会在启动时连接到它提供服务。

运行报错

app Error: Failed to launch the browser process!
Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted
[0203/185746.127214:ERROR:process_memory_range.cc(86)] read out of range
[0203/185746.127284:ERROR:elf_image_reader.cc(606)] missing nul-terminator
[0203/185746.127989:WARNING:process_reader_linux.cc(95)] sched_getscheduler: Function not implemented (38)
[0203/185746.128150:WARNING:process_reader_linux.cc(95)] sched_getscheduler: Function not implemented (38)

                    TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md
                    
                        at onClose (/koishi/node_modules/puppeteer-core/lib/cjs/puppeteer/node/BrowserRunner.js:299:20)
                        at ChildProcess.<anonymous> (/koishi/node_modules/puppeteer-core/lib/cjs/puppeteer/node/BrowserRunner.js:290:24)
                        at ChildProcess.emit (node:events:525:35)
                        at ChildProcess._handle.onexit (node:internal/child_process:291:12)

尝试关闭无头模式,但问题依旧(

FR: launch函数

想要实现一个什么效果

新增一个「launch」函数,用于启动一个独立的浏览器

返回值可为Promise

因为什么做不到

我有个对于「九天」平台的工具箱,需要使用pptr进行登录后拦截数据,但是如果两个人同时使用命令就会导致覆盖cookie

如果什么就能做到了

同浏览器不同page隔离cookie

或者不同浏览器之间隔离cookie

如果有别的办法做到请告诉我

Bug: canvas.loadImage 加载本地图片报错

image

这里 似乎只能加载图片 http 协议的 url,加载本地图片 file:////root/ks/data/skk.jpg 时会报错

2023-11-20 21:12:05 [W] command help-pro 
                        AggregateError
                            at request (/root/ks/node_modules/cordis-axios/lib/index.js:153:21)
                            at http.axios (/root/ks/node_modules/cordis-axios/lib/index.js:182:16)
                            at _Quester.file (/root/ks/node_modules/cordis-axios/lib/index.js:256:42)
                            at _Quester.file (/root/ks/node_modules/@satorijs/satori/lib/index.js:55:18)
                            at ImageElement.initialize (/root/ks/node_modules/koishi-plugin-puppeteer/lib/canvas.js:127:46)
                            at Proxy.loadImage (/root/ks/node_modules/koishi-plugin-puppeteer/lib/canvas.js:180:21)
                            at initTheme (/root/ks/node_modules/koishi-plugin-help-pro/lib/render_canvas.js:191:34)
                            at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
                            at async render_categroy (/root/ks/node_modules/koishi-plugin-help-pro/lib/render_canvas.js:53:20)
                            at async renderCategroy (/root/ks/node_modules/koishi-plugin-help-pro/lib/index.js:454:15)
                            at async _Command.<anonymous> (/root/ks/node_modules/koishi-plugin-help-pro/lib/index.js:160:28)
                            at async Array.<anonymous> (/root/ks/node_modules/@koishijs/core/lib/index.cjs:1331:14)
                            at async _Command.execute (/root/ks/node_modules/@koishijs/core/lib/index.cjs:1346:22)
                            at async /root/ks/node_modules/@koishijs/core/lib/index.cjs:2174:22
                            at async _Session.withScope (/root/ks/node_modules/@koishijs/core/lib/index.cjs:2076:22)
                            at async next (/root/ks/node_modules/@koishijs/core/lib/index.cjs:1053:16)
                            at async next (/root/ks/node_modules/@koishijs/core/lib/index.cjs:1053:16)
                            at async _Processor._handleMessage (/root/ks/node_modules/@koishijs/core/lib/index.cjs:1064:22)

Bug: 缺少 canvas 服务的声明合并

如何复现

  1. 安装 koishi-plugin-puppeteer
  2. 创建一个新插件
  3. index.ts 中写入如下代码
import { Context, Schema } from "koishi";
import {} from "koishi-plugin-puppeteer";

export const name = "test-plugin";

export const inject = ["canvas"];

export interface Config {}

export const Config: Schema<Config> = Schema.object({});

export async function apply(ctx: Context) {
  const c = (await ctx.canvas.createCanvas(1, 1)).getContext("2d");
  console.log(c.measureText("test text"));
}
  1. 编译插件

预期结果

因为 Puppeteer 插件提供了 canvas 服务,因此可以正常编译。

实际结果

$ yarn run build test-plugin  
external/test-plugin/src/index.ts:13:24 - error TS2339: Property 'canvas' does not exist on type 'Context'.

13   const c = (await ctx.canvas.createCanvas(1, 1)).getContext("2d");
                          ~~~~~~

TSFILE: /home/l/workspace/koishi-app/external/test-plugin/tsconfig.tsbuildinfo

Found 1 error.

可能的修复措施

packages/core/src/index.ts

declare module 'koishi' {
  interface Context {
    puppeteer: Puppeteer;
    canvas: Canvas;
  }
}

DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.

(node:13084) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
    at node:punycode:3:9
    at BuiltinModule.compileForInternalLoader (node:internal/bootstrap/realm:398:7)
    at BuiltinModule.compileForPublicLoader (node:internal/bootstrap/realm:337:10)
    at loadBuiltinModule (node:internal/modules/helpers:104:7)
    at Module._load (node:internal/modules/cjs/loader:999:17)
    at Module.require (node:internal/modules/cjs/loader:1230:19)
    at require (node:internal/modules/helpers:179:18)
    at Object.<anonymous> (F:\koishi-dev\node_modules\whatwg-url\lib\url-state-machine.js:2:18)
    at Module._compile (node:internal/modules/cjs/loader:1368:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1426:10)
node-fetch@npm:2.7.0
└─ whatwg-url@npm:5.0.0 (via npm:^5.0.0)

cross-fetch@npm:4.0.0
└─ node-fetch@npm:2.7.0 [643a2] (via npm:^2.6.7 [643a2])

puppeteer-core@npm:22.3.0
└─ cross-fetch@npm:4.0.0 (via npm:4.0.0)

解决办法:更新 puppeteer-core^22.5.0

puppeteer/puppeteer@d5da9fb
22.5.0 移除了 cross-fetch 依赖

希望能加入`headless: "new"` 配置项消除 warning

日志输出

Puppeteer old Headless deprecation warning:
    In the near feature `headless: true` will default to the new Headless mode
    for Chrome instead of the old Headless implementation. For more
    information, please see https://developer.chrome.com/articles/new-headless/.
    Consider opting in early by passing `headless: "new"` to `puppeteer.launch()`
    If you encounter any bugs, please report them to https://github.com/puppeteer/puppeteer/issues/new/choose.

现在的配置项只能是一个布尔值

headless: Schema.boolean()

Feature: 调整pptr渲染图片的格式(或大小)

Describe the problem related to the feature request

渲染出的图片(png)过大,对小水管不是很友好

Describe the solution you'd like

修改渲染图片的格式或者内部压缩

Describe alternatives you've considered

No response

Additional context

No response

bug: 调用 ctx.puppeteer.render 时无法加载本地资源

插件在渲染 html 内置组件时,如果使用诸如 file:///home/ubuntu/imgs/1.png 这样的本地资源,可以正常加载。但如果在调用 ctx.puppeteer.render 时使用本地资源,则会无法加载。

Puppeteers 打开标签时默认的 URL 为 about:blank,此时 Chrome 无法加载本地资源(Not allowed to load local resource)。但渲染内置组件之前,插件会先做以下操作:

await page.goto('file:///' + resolve(__dirname, '../index.html'))

这样标签页的 URL 变成了本地页面,因此之后可以正常加载本地资源了。但是,ctx.puppeteer.render 在渲染前并不会做类似的操作,所以页面并不能正常显示。

能否在 ctx.puppeteer.render 中也加上这个操作?如果不行,这么做会导致什么其他的问题吗?

Bug(?): `<html>` looks like not accepting attributes like `lang`?

Summary

Bonjour, I am the author of the FFXIV plugin koishi-plugin-ffxiv-macrodict, which provides a convenient way to read the description of the ffxiv's game macros (text commands).

Recently I tried to switch the render function from page.SetContent() and page.screenshot() to use the <html> message element provided by puppeteer plugin. But now it looks like the font-family-es CSS that I set for various languages are not functional, which makes the resulting character weird, especially in CJK (Chinese, Japanese and Korean characters).

So I guess that is because the html message not accepting the lang attributes?

Code

Here's how I utilize the puppeteer plugin for the image generation.

<html lang=lang>
<head>
  <style>{css`
    /* ... */
    [lang="zh"] body {
      font-family: 'Microsoft Yahei UI', SimHei, Consolas, 'Courier New', monospace;
    }
    [lang="ja"] body {
      font-family: 'Yu Gothic', 'Yu Gothic UI', 'Meiryo UI', 'Meiryo', 'MS Gothic', Consolas, 'Courier New', monospace;
    }
    [lang="ko"] body {
      font-family: 'Malgun Gothic', 'Apple SD Gothic Neo', 'Nanum Gothic', Consolas, 'Courier New', monospace;
    }
  `}
</head>
{ /* ... */ }
</html>

无法渲染html文件

let template = fs.readFileSync(`help.html`, 'utf8')
console.log(template)
return  `<html>${template}</html>`

报错
image

docker内无法使用

由于docker内没有浏览器内核..
导致其找不到可执行文件。
请问能否内置Chromium呢

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.