puppeteer怎么等到某个元素出现在页面中才执行程序?

2023年1月30日

这个问题出现的场景是我想要把puppeteer文档转为pdf文档方便阅读和做笔记,所以程序思路是:

  1. 前往这个网页

  1. 获取到目录上的所有链接

  1. 循环前往链接对应的网页并保存为pdf

但当程序运行时却出现错误:

根据经验就是querySelectorAll前面的dom没有找到,然后我通过设置headless: false取消无头模式来查看程序运行的具体过程,结果发现一打开网页出现的并不是目标的网页内容,而是:

所以我就需要等到真正的网页出现再执行核心的程序。

我首先想到的是page.waitForNavigation,因为之前我接触了解过:

  await page.goto(basePage);
  console.log(1)
  await page.waitForNavigation({ waitUntil: "networkidle0" });
  console.log(2)

结果发现出现了真正的内容,确实没有报错,但当内容出现后程序却停住了,最后超时报错:

然后我就尝试改变waitUntil的参数,但结果都一样。

然后我又想page.waitForNavigation是否是这样用的,根据网上查阅Are waitUntil of page.goto and page.waitForNavigation the same?发现:

Usually waitForNavigation is used with a click, where clicking might cause a navigation in the browser.

而且puppeteer文档里的示例就是用的click:

const [response] = await Promise.all([
  page.waitForNavigation(), // The promise resolves after navigation has finished
  page.click('a.my-link'), // 点击该链接将间接导致导航(跳转)
]);

然后我又运行了程序,在程序停止时随便点击网页上的一个链接,然后程序又正常运行了:

我想page.waitForNavigation应该是等待网页上的Navigation的触发,可以简单认为是网址改变,然后等待网址改变后网站加载到什么程度就是设置的waitUntil了。然而我的代码是在page.goto后执行page.waitForNavigation,这时并不存在navigation,所以由于是await就一直等待(测试如果没有await就会出现最开始的querySelectorAll的错误)直到超时报错。

那么我们还要再考虑使用page.waitForNavigation吗?我们就要分析是否有使用的场景。可以知道首先前往网站,然后有一个缓冲的过程,紧接着在相同的网址下加载出真正的内容。同时page.waitForNavigation并没有与链接有关的选项,那么就只能是网页上的navigation来触发,但本项目的过程中没有这个navigation过程而是等待这个链接加载完成。同时通过Are waitUntil of page.goto and page.waitForNavigation the same?可以了解到page.goto可以通过waitUntil来设置满足什么条件认为页面跳转完成,而我们的需要正好就是那个缓冲过程结束就是完成了。

于是我采用了networkidle0,等待所有请求结束:

  await page.goto(basePage, { waitUntil: 'networkidle0' });

结果满足需求。但我此时又有一个想法:puppeteer可以等到某个元素出现再执行相关的程序吗?

我想要的就是等到网站真正内容中的目录元素出现,也就是querySelectorAll的dom出现后再执行,那么就不会报出最开始的错误了。

通过查阅文档Please give us a few seconds to download Puppeteer releases for the first time. Next time we'll do i发现有相关的方法——page.waitForSelector(selector[, options])

于是我以querySelectorAll的dom为选择器:

  await page.goto(basePage);
  await page.waitForSelector("sidebar-component");

结果也能满足需求。最终我选择采用page.waitForSelector,我觉得它更加准确和适合这个场景。

还有一个方法就是设置一个等待时间,在这个时间内缓冲过程结束而真正的内容出现:

  await page.goto(basePage);
  await new Promise(r => setTimeout(r, 6000));

但缺点很大,就是该设置什么时间呢?也许在某个时刻自己的机器和网络情况下适用,但任一条件改变后都可能失效。你可能会想设置一个很长的时间就是了,但还是有可能不够长,同时效率也很低,所以不是一个很好的方法。

智能网联汽车的安全员高级考试涉及多个方面的专业知识,包括但不限于自动驾驶技术原理、车辆传感器融合、网络安全防护以及法律法规等内容。以下是针对该主题的一些核心知识点解析: ### 关于智能网联车安全员高级考试的核心内容 #### 1. 自动驾驶分级标准 国际自动机工程师学会(SAE International)定义了六个级别的自动驾驶等级,从L0到L5[^1]。其中,L3及以上级别需要安全员具备更高的应急处理能力。 #### 2. 车辆感知系统的组成与功能 智能网联车通常配备多种传感器,如激光雷达、毫米波雷达、摄像头超声波传感器等。这些设备协同工作以实现环境感知、障碍物检测等功能[^2]。 #### 3. 数据通信与网络安全 智能网联车依赖V2X(Vehicle-to-Everything)技术进行数据交换,在此过程中需防范潜在的网络攻击风险,例如中间人攻击或恶意软件入侵[^3]。 #### 4. 法律法规要求 不同国家地区对于无人驾驶测试及运营有着严格的规定,考生应熟悉当地交通法典中有关自动化驾驶部分的具体条款[^4]。 ```python # 示例代码:模拟简单决策逻辑 def decide_action(sensor_data): if sensor_data['obstacle'] and not sensor_data['emergency']: return 'slow_down' elif sensor_data['pedestrian_crossing']: return 'stop_and_yield' else: return 'continue_driving' example_input = {'obstacle': True, 'emergency': False, 'pedestrian_crossing': False} action = decide_action(example_input) print(f"Action to take: {action}") ``` 需要注意的是,“橙点同学”作为特定平台上的学习资源名称,并不提供官方认证的标准答案集;建议通过正规渠道获取教材并参加培训课程来准备此类资格认证考试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值