page.hover() 无效
page.hover() having no effect
描述
我网站上的一些按钮在悬停时会改变颜色,但是当使用 deno-puppeteer 时,它似乎没有任何效果。
相关代码:
import { puppeteer } from './deps.ts';
const browser = await puppeteer.launch();
const page = await browser.newPage();
const url = 'https://sweet-snake-49.deno.dev';
await page.goto(url);
await page.setViewport({
width: 1600,
height: 1200
});
await page.hover('#left');
await page.screenshot({ path: Deno.cwd() + '/example.png' });
await browser.close();
要重现的完整项目here。
预期输出
悬停时,我希望颜色会变成带有框阴影的黄色,但不幸的是,好像没有悬停归因于我的按钮。
发件人:
收件人:
问题
如何让 page.hover()
在我的 #left
按钮上工作?
它似乎与 deno 无关,因为 nodejs 正在发生完全相同的问题
您应该等待该元素存在,然后尝试与在 DOM 中找到的元素进行交互。
使用 Puppeteer 页面 waitForSelector 的示例:
import { puppeteer } from './deps.ts';
const browser = await puppeteer.launch();
const page = await browser.newPage();
const url = 'https://sweet-snake-49.deno.dev';
await page.goto(url);
await page.setViewport({
width: 1600,
height: 1200
});
// wait for element before trying to hover
page.waitForSelector('#left').then(() =>
await page.hover('#left');
await page.screenshot({ path: Deno.cwd() + '/example.png' });
);
await browser.close();
我使用了一个 Docker 容器(因为我不喜欢使用 deno-puppeteer 要求的自由权限来禁用安全沙箱),所以我的配置与你的有点不同.
我已经修改了 Dockerfile template from the deno-puppeteer
repo 和您的源文件,我在屏幕截图中获得了成功的悬停状态:
Note that the target page you linked to uses the glyph ◀
(U+25C0 BLACK LEFT-POINTING TRIANGLE) for the text inside the left button — and, it doesn't appear to render in the container: the screenshot shows a default box character in place of it. I suppose a compatible font would need to be installed as an additional step in the Dockerfile in order to address this: more debugging would be required.
为了让代码在 Stack Overflow 上可用(而不是依赖外部托管),我将内联复制目录中的文件内容(我将其命名为 so-70731163
您问题的 ID),以及控制台 input/output:
./.vscode/settings.json
{
"deno.enable": true,
"deno.lint": true,
"deno.unstable": true,
"deno.config": "./src/deno.json"
}
./src/deno.json
{
"compilerOptions": {
"lib": [
"deno.window",
"dom",
"dom.iterable"
]
}
}
./src/deps.ts
export * as path from 'https://deno.land/std@0.122.0/path/mod.ts';
export {
assert,
assertExists,
} from 'https://deno.land/std@0.122.0/testing/asserts.ts';
export {
default as puppeteer,
type ElementHandle,
type ScreenshotOptions,
} from 'https://deno.land/x/puppeteer@9.0.2/mod.ts';
./src/main.ts
import {
assert,
assertExists,
path,
puppeteer,
type ElementHandle,
type ScreenshotOptions,
} from './deps.ts';
// Create data directory if it doesn't already exist
const dataDir = path.resolve('container-data');
await Deno.mkdir(dataDir, {recursive: true});
// Browser launch options required for usage in Docker
// https://github.com/lucacasonato/deno-puppeteer/issues/16#issuecomment-842784232
// https://github.com/lucacasonato/deno-puppeteer/blob/9.0.2/examples/docker.js
const dockerLaunchArgs = [
'--no-sandbox',
'--disable-dev-shm-usage',
];
const browser = await puppeteer.launch({args: dockerLaunchArgs});
const page = await browser.newPage();
await page.setViewport({width: 1600, height: 1200});
const url = 'https://sweet-snake-49.deno.dev';
await page.goto(url);
// Get handle for left button (used in next step) and hover it
const leftBtnHandle = await page.$('button#left');
assertExists(leftBtnHandle);
await leftBtnHandle.hover();
// Get handle for controls container (for screenshot in next step)
const getControls = (leftBtn: HTMLButtonElement) => leftBtn.closest('section');
const controlsHandle =
(await leftBtnHandle.evaluateHandle<ElementHandle>(getControls)).asElement();
assertExists(controlsHandle);
// Instead of using Puppeteer API to save screenshot,
// get raw buffer data for more control
const screenshotOpts: ScreenshotOptions = {encoding: 'binary', type: 'png'};
const pngData = await controlsHandle.screenshot(screenshotOpts);
assert(pngData instanceof Uint8Array);
const screenshotPath = path.join(dataDir, 'controls.png');
await Deno.writeFile(screenshotPath, pngData);
await browser.close();
./docker-build
docker build --tag so-70731163 .
./docker-run
docker run -it \
--rm \
--name so-70731163 \
--mount type=bind,source="$(pwd)",destination=/app \
so-70731163
./Dockerfile
FROM debian:buster-slim
ENV DENO_VERSION=1.18.0
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get -qq update \
&& apt-get -qq install -y --no-install-recommends \
curl \
ca-certificates \
unzip \
# ↓ https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix
# Since I want to leave the contents of troubleshooting.md as it is, ca-certificates is intentionally duplicated here.
ca-certificates \
fonts-liberation \
libappindicator3-1 \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libc6 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libexpat1 \
libfontconfig1 \
libgbm1 \
libgcc1 \
libglib2.0-0 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libstdc++6 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxi6 \
libxrandr2 \
libxrender1 \
libxss1 \
libxtst6 \
lsb-release \
wget \
xdg-utils \
# ↑ https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix
# ↓ Added based on the information obtained from by console.log(line) at https://deno.land/x/puppeteer@9.0.2/src/deno/BrowserRunner.ts#L168.
libdrm2 \
libxkbcommon0 \
libxshmfence1 \
# ↑ Added based on the information obtained from by console.log(line) at https://deno.land/x/puppeteer@9.0.2/src/deno/BrowserRunner.ts#L168.
&& curl -fsSL https://github.com/denoland/deno/releases/download/v${DENO_VERSION}/deno-x86_64-unknown-linux-gnu.zip \
--output deno.zip \
&& unzip deno.zip \
&& rm deno.zip \
&& chmod 755 deno \
&& mv deno /usr/bin/deno \
&& apt-get -qq remove --purge -y \
curl \
# Do not remove ca-certificates as it is required by puppeteer.
# ca-certificates \
unzip \
&& apt-get -y -qq autoremove \
&& apt-get -qq clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN useradd --uid 1993 --user-group deno \
&& mkdir /deno-dir/ \
&& chown deno:deno /deno-dir/
ENV DENO_DIR /deno-dir/
# --- PLACE CUSTOM COMMANDS BELOW --- #
WORKDIR /app
# Bind CWD instead of copying
# COPY . .
# https://deno.land/x/puppeteer@9.0.2#installation
# In your real script, replace the installation script with https://deno.land/x/puppeteer@9.0.2/install.ts
RUN PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/puppeteer@9.0.2/install.ts
ENTRYPOINT ["deno"]
CMD ["run", "-A", "--no-check", "--unstable", "./src/main.ts"]
在控制台中:
so-70731163 % ./docker-build
# Lots of Docker build output messages...
so-70731163 % ./docker-run
# Lines showing compilation info: Download moduleURL...
之后,上面的截图被写入./container-data/controls.png
。
要删除内置的 docker 图像:
docker image rm so-70731163
描述
我网站上的一些按钮在悬停时会改变颜色,但是当使用 deno-puppeteer 时,它似乎没有任何效果。
相关代码:
import { puppeteer } from './deps.ts';
const browser = await puppeteer.launch();
const page = await browser.newPage();
const url = 'https://sweet-snake-49.deno.dev';
await page.goto(url);
await page.setViewport({
width: 1600,
height: 1200
});
await page.hover('#left');
await page.screenshot({ path: Deno.cwd() + '/example.png' });
await browser.close();
要重现的完整项目here。
预期输出
悬停时,我希望颜色会变成带有框阴影的黄色,但不幸的是,好像没有悬停归因于我的按钮。
发件人:
收件人:
问题
如何让 page.hover()
在我的 #left
按钮上工作?
它似乎与 deno 无关,因为 nodejs 正在发生完全相同的问题
您应该等待该元素存在,然后尝试与在 DOM 中找到的元素进行交互。
使用 Puppeteer 页面 waitForSelector 的示例:
import { puppeteer } from './deps.ts';
const browser = await puppeteer.launch();
const page = await browser.newPage();
const url = 'https://sweet-snake-49.deno.dev';
await page.goto(url);
await page.setViewport({
width: 1600,
height: 1200
});
// wait for element before trying to hover
page.waitForSelector('#left').then(() =>
await page.hover('#left');
await page.screenshot({ path: Deno.cwd() + '/example.png' });
);
await browser.close();
我使用了一个 Docker 容器(因为我不喜欢使用 deno-puppeteer 要求的自由权限来禁用安全沙箱),所以我的配置与你的有点不同.
我已经修改了 Dockerfile template from the deno-puppeteer
repo 和您的源文件,我在屏幕截图中获得了成功的悬停状态:
Note that the target page you linked to uses the glyph
◀
(U+25C0 BLACK LEFT-POINTING TRIANGLE) for the text inside the left button — and, it doesn't appear to render in the container: the screenshot shows a default box character in place of it. I suppose a compatible font would need to be installed as an additional step in the Dockerfile in order to address this: more debugging would be required.
为了让代码在 Stack Overflow 上可用(而不是依赖外部托管),我将内联复制目录中的文件内容(我将其命名为 so-70731163
您问题的 ID),以及控制台 input/output:
./.vscode/settings.json
{
"deno.enable": true,
"deno.lint": true,
"deno.unstable": true,
"deno.config": "./src/deno.json"
}
./src/deno.json
{
"compilerOptions": {
"lib": [
"deno.window",
"dom",
"dom.iterable"
]
}
}
./src/deps.ts
export * as path from 'https://deno.land/std@0.122.0/path/mod.ts';
export {
assert,
assertExists,
} from 'https://deno.land/std@0.122.0/testing/asserts.ts';
export {
default as puppeteer,
type ElementHandle,
type ScreenshotOptions,
} from 'https://deno.land/x/puppeteer@9.0.2/mod.ts';
./src/main.ts
import {
assert,
assertExists,
path,
puppeteer,
type ElementHandle,
type ScreenshotOptions,
} from './deps.ts';
// Create data directory if it doesn't already exist
const dataDir = path.resolve('container-data');
await Deno.mkdir(dataDir, {recursive: true});
// Browser launch options required for usage in Docker
// https://github.com/lucacasonato/deno-puppeteer/issues/16#issuecomment-842784232
// https://github.com/lucacasonato/deno-puppeteer/blob/9.0.2/examples/docker.js
const dockerLaunchArgs = [
'--no-sandbox',
'--disable-dev-shm-usage',
];
const browser = await puppeteer.launch({args: dockerLaunchArgs});
const page = await browser.newPage();
await page.setViewport({width: 1600, height: 1200});
const url = 'https://sweet-snake-49.deno.dev';
await page.goto(url);
// Get handle for left button (used in next step) and hover it
const leftBtnHandle = await page.$('button#left');
assertExists(leftBtnHandle);
await leftBtnHandle.hover();
// Get handle for controls container (for screenshot in next step)
const getControls = (leftBtn: HTMLButtonElement) => leftBtn.closest('section');
const controlsHandle =
(await leftBtnHandle.evaluateHandle<ElementHandle>(getControls)).asElement();
assertExists(controlsHandle);
// Instead of using Puppeteer API to save screenshot,
// get raw buffer data for more control
const screenshotOpts: ScreenshotOptions = {encoding: 'binary', type: 'png'};
const pngData = await controlsHandle.screenshot(screenshotOpts);
assert(pngData instanceof Uint8Array);
const screenshotPath = path.join(dataDir, 'controls.png');
await Deno.writeFile(screenshotPath, pngData);
await browser.close();
./docker-build
docker build --tag so-70731163 .
./docker-run
docker run -it \
--rm \
--name so-70731163 \
--mount type=bind,source="$(pwd)",destination=/app \
so-70731163
./Dockerfile
FROM debian:buster-slim
ENV DENO_VERSION=1.18.0
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get -qq update \
&& apt-get -qq install -y --no-install-recommends \
curl \
ca-certificates \
unzip \
# ↓ https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix
# Since I want to leave the contents of troubleshooting.md as it is, ca-certificates is intentionally duplicated here.
ca-certificates \
fonts-liberation \
libappindicator3-1 \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libc6 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libexpat1 \
libfontconfig1 \
libgbm1 \
libgcc1 \
libglib2.0-0 \
libgtk-3-0 \
libnspr4 \
libnss3 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libstdc++6 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxi6 \
libxrandr2 \
libxrender1 \
libxss1 \
libxtst6 \
lsb-release \
wget \
xdg-utils \
# ↑ https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix
# ↓ Added based on the information obtained from by console.log(line) at https://deno.land/x/puppeteer@9.0.2/src/deno/BrowserRunner.ts#L168.
libdrm2 \
libxkbcommon0 \
libxshmfence1 \
# ↑ Added based on the information obtained from by console.log(line) at https://deno.land/x/puppeteer@9.0.2/src/deno/BrowserRunner.ts#L168.
&& curl -fsSL https://github.com/denoland/deno/releases/download/v${DENO_VERSION}/deno-x86_64-unknown-linux-gnu.zip \
--output deno.zip \
&& unzip deno.zip \
&& rm deno.zip \
&& chmod 755 deno \
&& mv deno /usr/bin/deno \
&& apt-get -qq remove --purge -y \
curl \
# Do not remove ca-certificates as it is required by puppeteer.
# ca-certificates \
unzip \
&& apt-get -y -qq autoremove \
&& apt-get -qq clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN useradd --uid 1993 --user-group deno \
&& mkdir /deno-dir/ \
&& chown deno:deno /deno-dir/
ENV DENO_DIR /deno-dir/
# --- PLACE CUSTOM COMMANDS BELOW --- #
WORKDIR /app
# Bind CWD instead of copying
# COPY . .
# https://deno.land/x/puppeteer@9.0.2#installation
# In your real script, replace the installation script with https://deno.land/x/puppeteer@9.0.2/install.ts
RUN PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/puppeteer@9.0.2/install.ts
ENTRYPOINT ["deno"]
CMD ["run", "-A", "--no-check", "--unstable", "./src/main.ts"]
在控制台中:
so-70731163 % ./docker-build
# Lots of Docker build output messages...
so-70731163 % ./docker-run
# Lines showing compilation info: Download moduleURL...
之后,上面的截图被写入./container-data/controls.png
。
要删除内置的 docker 图像:
docker image rm so-70731163