Headless puppeteer 屏幕截图未呈现 WebGL canvas
Headless puppeteer screenshot not rendering WebGL canvas
我正在尝试在无头模式下使用 puppeteer 截取 website (in which I control) 的屏幕截图。
问题是,我的网站上有一个 WebGL canvas 无法在无头模式屏幕截图中呈现(但在有头模式下工作)。
我在无头模式下得到的只是一个黑色的 PNG。
我试过将 WebGL 上下文参数更改为多个组合,但没有任何效果。
我使用的是 puppeteer 5.5.0 版和 chromium 88.0.4298.0 版
这是我的 puppeteer 爬虫代码:
const puppeteer = require("puppeteer");
const url = "https://phcs93.github.io/genesis/";
async function crawl () {
const browser = await puppeteer.launch({
headless: true,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--mute-audio'
]
});
const page = await browser.newPage();
await page.goto(url, {
"waitUntil": "networkidle0",
"timeout": 0
});
await page.screenshot({ path: "screenshot.png" });
await browser.close();
}
(async () => await crawl())();
这些是我在网站的 WebGL 上下文中使用的当前参数:
const gl = canvas.getContext("webgl2", {
preserveDrawingBuffer: true,
alpha: false,
antialias: true,
premultipliedAlpha: true
});
经过大量调试,发现问题所在:
在我的一个着色器 (gradient.glsl) 中,我有这个:
uniform float[256] breakpoints;
uniform vec4[256] colors;
改成这样,问题解决:
uniform float[122] breakpoints;
uniform vec4[122] colors;
两个数组的任何大于 122 的值都不起作用。
现在更奇怪的部分来了,这个有效:
uniform float[244] breakpoints; // 245 or more wont work
// uniform vec4[122] colors;
这行不通:
// uniform float[122] breakpoints;
uniform vec4[244] colors; // only 243 or less
我还没有进一步测试,看起来像无头模式的某种内存限制?
提示: 可以使用 puppeteer 从页面捕获所有控制台消息,只需在 page.goto
:
之前添加
page.on('console', message => console.log(`${message.type().substr(0, 3).toUpperCase()} ${message.text()}`));
page.on('pageerror', ({ message }) => console.log(message));
page.on('response', response => console.log(`${response.status()} ${response.url()}`));
page.on('requestfailed', request => console.log(`${request.failure().errorText} ${request.url()}`));
这样做可以节省我很多调试时间。
我正在尝试在无头模式下使用 puppeteer 截取 website (in which I control) 的屏幕截图。
问题是,我的网站上有一个 WebGL canvas 无法在无头模式屏幕截图中呈现(但在有头模式下工作)。
我在无头模式下得到的只是一个黑色的 PNG。
我试过将 WebGL 上下文参数更改为多个组合,但没有任何效果。
我使用的是 puppeteer 5.5.0 版和 chromium 88.0.4298.0 版
这是我的 puppeteer 爬虫代码:
const puppeteer = require("puppeteer");
const url = "https://phcs93.github.io/genesis/";
async function crawl () {
const browser = await puppeteer.launch({
headless: true,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--mute-audio'
]
});
const page = await browser.newPage();
await page.goto(url, {
"waitUntil": "networkidle0",
"timeout": 0
});
await page.screenshot({ path: "screenshot.png" });
await browser.close();
}
(async () => await crawl())();
这些是我在网站的 WebGL 上下文中使用的当前参数:
const gl = canvas.getContext("webgl2", {
preserveDrawingBuffer: true,
alpha: false,
antialias: true,
premultipliedAlpha: true
});
经过大量调试,发现问题所在:
在我的一个着色器 (gradient.glsl) 中,我有这个:
uniform float[256] breakpoints;
uniform vec4[256] colors;
改成这样,问题解决:
uniform float[122] breakpoints;
uniform vec4[122] colors;
两个数组的任何大于 122 的值都不起作用。
现在更奇怪的部分来了,这个有效:
uniform float[244] breakpoints; // 245 or more wont work
// uniform vec4[122] colors;
这行不通:
// uniform float[122] breakpoints;
uniform vec4[244] colors; // only 243 or less
我还没有进一步测试,看起来像无头模式的某种内存限制?
提示: 可以使用 puppeteer 从页面捕获所有控制台消息,只需在 page.goto
:
page.on('console', message => console.log(`${message.type().substr(0, 3).toUpperCase()} ${message.text()}`));
page.on('pageerror', ({ message }) => console.log(message));
page.on('response', response => console.log(`${response.status()} ${response.url()}`));
page.on('requestfailed', request => console.log(`${request.failure().errorText} ${request.url()}`));
这样做可以节省我很多调试时间。