gpt4 book ai didi

javascript - Puppeteer/Node.js 只要按钮存在就单击它 - 当它不再存在时,开始操作

转载 作者:行者123 更新时间:2023-12-03 12:16:11 27 4
gpt4 key购买 nike

有一个网页包含许多不断更新的数据行。

行数是固定的,所以旧行被循环出并且不存储在任何地方。

此页面由“加载更多”按钮分解,该按钮将出现,直到所有存储的行都显示在页面上。

我需要在 Puppeteer/Node.js 中编写一个脚本,单击该按钮,直到它不再存在于页面上......

然后

...阅读页面上的所有文本。 (我已经完成了这部分脚本。)

我是 Puppeteer 的新手,不知道如何设置。任何帮助将不胜感激。

编辑:

我添加了这个 block :

  const cssSelector = await page.evaluate(() => document.cssSelector('.u-field-button Button-button-18U-i'));

// Click the "load more" button repeatedly until it no longer appears
const isElementVisible = async (page, cssSelector) => {
await page.waitForSelector(cssSelector, { visible: true, timeout: 2000 })
.catch(() => {
return false;
});
return true;
};

let loadMoreVisible = await isElementVisible(page, cssSelector);
while (loadMoreVisible) {
await page.click(cssSelector);
loadMoreVisible = await isElementVisible(page, cssSelector);
}

但我收到此错误:
Error: Evaluation failed: TypeError: document.cssSelector is not a function
at __puppeteer_evaluation_script__:1:17
at ExecutionContext.evaluateHandle (/Users/reallymemorable/node_modules/puppeteer/lib/ExecutionContext.js:124:13)
at process.internalTickCallback (internal/process/next_tick.js:77:7)
-- ASYNC --
at ExecutionContext.<anonymous> (/Users/reallymemorable/node_modules/puppeteer/lib/helper.js:144:27)
at ExecutionContext.evaluate (/Users/reallymemorable/node_modules/puppeteer/lib/ExecutionContext.js:58:31)
at ExecutionContext.<anonymous> (/Users/reallymemorable/node_modules/puppeteer/lib/helper.js:145:23)
at Frame.evaluate (/Users/reallymemorable/node_modules/puppeteer/lib/FrameManager.js:439:20)
at process.internalTickCallback (internal/process/next_tick.js:77:7)
-- ASYNC --
at Frame.<anonymous> (/Users/reallymemorable/node_modules/puppeteer/lib/helper.js:144:27)
at Page.evaluate (/Users/reallymemorable/node_modules/puppeteer/lib/Page.js:736:43)
at Page.<anonymous> (/Users/reallymemorable/node_modules/puppeteer/lib/helper.js:145:23)
at /Users/reallymemorable/Documents/scripts.scrapers/squarespace.ip.scraper/squarespace5.js:32:34
at process.internalTickCallback (internal/process/next_tick.js:77:7)
(node:8009) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:8009) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

最佳答案

好的,这就是我建议您为实现这一目标而做的事情。我将忽略您的数据始终有固定数量的行(也许将来会改变),而是会设置您是否通过不断单击来显示未知数量的数据行“加载更多”按钮。

因此,您要做的第一件事是设置一个方法,该方法决定是否在 UI 中显示“加载更多”按钮。您想通过编写如下方法来做到这一点:

const isElementVisible = async (page, cssSelector) => {
let visible = true;
await page
.waitForSelector(cssSelector, { visible: true, timeout: 2000 })
.catch(() => {
visible = false;
});
return visible;
};

一旦你传入你需要的 CSS 选择器(在这种情况下是你的“加载更多”按钮的选择器),这个方法将返回 true如果显示按钮和 false如果不是。

您希望超时为 2000因为您要不断检查此按钮是否显示。如果不显示,超时将默认为 30000这对于让您的代码等待的时间太长了。所以我发现 2000是一个很好的妥协。 catch 的目的block 是为了捕获元素不再显示时将引发的错误 - 您想忽略引发错误的事实,因为您试图到达按钮不再显示的位置。您知道它不会在 X 次点击后显示。没关系。所以你需要 catch发生这种情况时完全绕过的错误。

然后,下一步是执行类似的操作,以让您的代码继续单击“加载更多”按钮,直到它不再可单击(即显示):
let loadMoreVisible = await isElementVisible(page, selectorForLoadMoreButton);
while (loadMoreVisible) {
await page
.click(selectorForLoadMoreButton)
.catch(() => {});
loadMoreVisible = await isElementVisible(page, selectorForLoadMoreButton);
}

这将不断检查按钮是否在您的 UI 中可见,如果显示则单击它,然后重复该过程直到不再显示该按钮。这可确保在您继续测试脚本的其余部分之前,所有数据行都将显示在 UI 中。

您还需要一个 catch阻止 click Action 如上图。原因是 headless模式移动得非常快。有时 UI 跟不上它的速度太快了。通常,在“显示更多”按钮的最后一次显示中, isElementVisible方法将在 UI 更新之前执行以消除按钮的存在,因此它返回 true实际上,现在不再显示选择器。然后,这会触发 click 的异常。请求,因为该元素不再存在。对我来说,解决这个问题的最干净的方法是添加空的 catch阻止 click这样,如果发生这种情况, click action 仍然会干净地绕过而不会使整个测试失败。

更新 1:

您只是错误地使用了 css 选择器。您的选择器应该是:
const cssSelector = '.u-field-button Button-button-18U-i'; // This is your CSS selector for the element

您不需要使用 evaluate方法。

更新 2:

好的,我已经添加了一些改进,我已经在几个不同的站点上广泛测试了这段代码,发现我自己的逻辑不太适合“一刀切”的方法来点击这些按钮,所以这是可能为什么你会得到这些异常(exception)。我已经用所做的所有更改更新了我的原始答案。

快速说明:我已经更新了 isElementVisible方法 while环形。

希望这可以帮助!

关于javascript - Puppeteer/Node.js 只要按钮存在就单击它 - 当它不再存在时,开始操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53200857/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com