等到 page.click returns 真
wait until page.click returns true
我正在抓取一个网站 weather.com,我想点击一个 html 元素来获取数据并显示它,然后我抓取该数据。
但它并不总是对我有用,大多数时候点击不会发生,我在尝试抓取这些元素时遇到错误
await page.waitFor('#twc-scrollabe > table > tbody > tr:nth-child(1)')
await page.click('#twc-scrollabe > table > tbody > tr:nth-child(1)')
我应该怎么做才能确保点击发生?
尝试指定您希望元素可见
await page.waitFor('#twc-scrollabe > table > tbody > tr:nth-child(1)', { visible:true })
(你注意到 {visible:true}
选项了吗?)
因为该元素可能在页面中,但在 waitFor
找到它时无法点击。
更多详情
- 当您将
waitFor
与选择器一起使用时,您实际上是在使用 waitForSelector
(see the docs)
waitForSelector
有一系列选项(see the docs)
- 其中一个选项是
visible
,文档说
wait for an element to be present in DOM and to be visible, i.e. to not have display: none
or visibility: hidden
CSS properties. Defaults to false
.
最后但同样重要的是:@FeliFong 问了你更多关于你的问题的事情,因为你没有提供足够的信息。你可以
- 指定您要从中获取的页面(如果它是公开的)
- 否则,您可以制作一个 GitHub 存储库,从您的项目中删除所有内容,只留下您正在谈论的 table 和 Puppeteer 脚本
- 一般来说,当你在做一个回购时,你自己会发现问题(我发生了很多很多次)
- 如果您无法通过自己制作回购来解决问题...没关系,我们就是为了解决这个问题,但下载回购、启动它、解决问题、制作一个要容易得多向您提出请求,然后返回这里给您一些解释。
它对我们有用,但主要对你有用,因为我试图回复你......但我不知道我提供的解决方案是否满足你的需求......如果我有机会用你的回购协议检查它,我会已经确定我已经解决了问题
[更新]
我在你提供给我的存储库上解决了这个问题,在 GitHub.
上接受我的 PR
我做了什么:我做了一些测试,但我不知道到底是什么 "blocks"(或者,更好的是,停止等待)那个网站上的 Puppeteer……但它没有重要的是,这是我的代码
let i = 0;
let found = false;
const maxRetries = 100;
do {
// waits for the element we need to click
await page.waitForSelector('#twc-scrollabe > table > tbody > tr:nth-child(1)')
// clicks it
await page.click('#twc-scrollabe > table > tbody > tr:nth-child(1)')
try {
// waits for the content we need
await page.waitForSelector('tr:nth-child(3) > td.sunrise > div > span:nth-child(2)', {timeout:1000});
// if the content won't be showed the code doesn't go on and the next line won't be reached
found = true;
} catch(e) {}
} while(!found || i > maxRetries) // the maxRetries variable is mere prudence
- 等待我们需要点击的元素
- 点击它
- 等待显示详细内容(超时1000毫秒)
- 如果无法显示,请重试(最多 100 次)
- 然后继续
第一次点击后,您的脚本会快速运行
我正在抓取一个网站 weather.com,我想点击一个 html 元素来获取数据并显示它,然后我抓取该数据。
但它并不总是对我有用,大多数时候点击不会发生,我在尝试抓取这些元素时遇到错误
await page.waitFor('#twc-scrollabe > table > tbody > tr:nth-child(1)')
await page.click('#twc-scrollabe > table > tbody > tr:nth-child(1)')
我应该怎么做才能确保点击发生?
尝试指定您希望元素可见
await page.waitFor('#twc-scrollabe > table > tbody > tr:nth-child(1)', { visible:true })
(你注意到 {visible:true}
选项了吗?)
因为该元素可能在页面中,但在 waitFor
找到它时无法点击。
更多详情
- 当您将
waitFor
与选择器一起使用时,您实际上是在使用waitForSelector
(see the docs) waitForSelector
有一系列选项(see the docs)- 其中一个选项是
visible
,文档说
wait for an element to be present in DOM and to be visible, i.e. to not have
display: none
orvisibility: hidden
CSS properties. Defaults tofalse
.
最后但同样重要的是:@FeliFong 问了你更多关于你的问题的事情,因为你没有提供足够的信息。你可以
- 指定您要从中获取的页面(如果它是公开的)
- 否则,您可以制作一个 GitHub 存储库,从您的项目中删除所有内容,只留下您正在谈论的 table 和 Puppeteer 脚本
- 一般来说,当你在做一个回购时,你自己会发现问题(我发生了很多很多次)
- 如果您无法通过自己制作回购来解决问题...没关系,我们就是为了解决这个问题,但下载回购、启动它、解决问题、制作一个要容易得多向您提出请求,然后返回这里给您一些解释。
它对我们有用,但主要对你有用,因为我试图回复你......但我不知道我提供的解决方案是否满足你的需求......如果我有机会用你的回购协议检查它,我会已经确定我已经解决了问题
[更新] 我在你提供给我的存储库上解决了这个问题,在 GitHub.
上接受我的 PR我做了什么:我做了一些测试,但我不知道到底是什么 "blocks"(或者,更好的是,停止等待)那个网站上的 Puppeteer……但它没有重要的是,这是我的代码
let i = 0;
let found = false;
const maxRetries = 100;
do {
// waits for the element we need to click
await page.waitForSelector('#twc-scrollabe > table > tbody > tr:nth-child(1)')
// clicks it
await page.click('#twc-scrollabe > table > tbody > tr:nth-child(1)')
try {
// waits for the content we need
await page.waitForSelector('tr:nth-child(3) > td.sunrise > div > span:nth-child(2)', {timeout:1000});
// if the content won't be showed the code doesn't go on and the next line won't be reached
found = true;
} catch(e) {}
} while(!found || i > maxRetries) // the maxRetries variable is mere prudence
- 等待我们需要点击的元素
- 点击它
- 等待显示详细内容(超时1000毫秒)
- 如果无法显示,请重试(最多 100 次)
- 然后继续 第一次点击后,您的脚本会快速运行