puppyteer

news/2025/2/14 8:31:28/
puppyteer

今天自己加了一个需求,尝试使用puppyteer来实现自动化录制视频,一开始的想法是先开启录屏工具,在使用puppyteer来做浏览器自动化,经过调研后发现有Puppeteer 屏幕录像机库,直接使用puppeteer-screen-recorder库。所以难点可能就是过验证码了。

可能会用到的方法:

  1. 启动浏览器:使用puppeteer.launch()启动浏览器实例,可以选择无头模式或有头模式(headless: false)。

  2. 打开新页面:使用browser.newPage()创建一个新页面。

  3. 导航到视频页面:使用page.goto(url)导航到包含视频的页面。

  4. 点击播放视频:使用page.click(selector)模拟点击视频播放按钮。

  5. 监控视频播放状态:这可能是实现中的一个技术难点。你可能需要通过JavaScript注入(使用page.evaluate())来访问页面中视频播放器的状态,并检测视频是否播放完毕。

  6. 录屏:Puppeteer本身不提供录屏功能。你可能需要使用其他工具或库(如ffmpeg)来实现屏幕录制。可以考虑在Puppeteer脚本外部启动录屏工具,或者使用Node.js的child_process模块来从Puppeteer脚本内部启动录屏进程。

  7. 点击下一节:视频播放完毕后,使用page.click(selector)模拟点击“下一节”按钮。

  8. 循环播放和录制:将上述步骤包装在一个循环中,直到所有视频播放并录制完毕。

技术难点:

  1. 视频播放状态监控:不同网站的视频播放器实现可能不同,需要具体分析如何获取视频播放状态。这可能涉及到对特定网站DOM结构和JavaScript的深入了解。

  2. 自动化录屏:Puppeteer本身不支持录屏。需要结合其他工具来实现录屏,这可能涉及到额外的配置和同步问题。

  3. 长时间任务的稳定性:长时间运行的自动化任务可能会遇到稳定性问题,如浏览器崩溃、网络问题等。需要考虑异常处理和恢复机制。

  4. 资源消耗:长时间录屏和视频播放可能会消耗大量计算机资源,特别是在有头模式下。

综上所述,虽然使用Puppeteer自动化录屏的想法是可行的,但实现起来需要解决一些技术挑战。你可能需要结合Puppeteer的API、JavaScript编程技巧以及其他录屏工具来实现这个功能。

video.onended = resolve;:
这行代码为视频元素设置了一个onended事件处理函数。onended是一个事件,当视频播放结束时会被触发。
将 resolve 函数赋值给 video.onended 意味着当视频播放结束时,resolve 函数将被调用,从而解决外部的Promise。
这个onended事件应该如何查看?是在JS代码中吗?

问题:

feature的大小要改变

方法:

# 设置页面窗口大小,适配Chrome浏览器
await page.setViewport(viewport={'width':1536,'height':768})
自动退出

这个TimeoutError错误表明Puppeteer在等待特定选择器对应的元素出现时超时了。默认情况下,page.waitForSelector方法会等待30秒(30000毫秒),如果在这段时间内没有找到匹配的元素,就会抛出这个错误。

出现这个错误可能有以下几个原因:

  1. 选择器不正确:提供的CSS选择器可能不匹配任何元素,或者页面结构已经发生了变化。

  2. 页面未完全加载:页面可能还没有完全加载,或者加载速度很慢,导致在超时时间内元素没有出现。

  3. 元素被动态加载:有些元素可能是通过JavaScript动态添加到页面上的,如果这些脚本没有执行或执行较慢,元素也不会出现。

  4. 网络或资源问题:网络延迟或资源加载问题可能导致页面加载不完整或超时。

解决方法:

  1. 检查选择器:确保选择器是正确的,并且确实能够匹配页面上的元素。

  2. 增加超时时间:你可以增加waitForSelector的超时时间,例如:

    await page.waitForSelector(selector, { timeout: 60000 }); // 等待60秒
    
  3. 等待页面加载:使用page.waitForNavigation等待页面导航事件完成,例如:

    await Promise.all([page.click('login-button-selector'), // 替换为实际的登录按钮选择器page.waitForNavigation({ waitUntil: 'networkidle0' }), // 等待网络空闲时
    ]);
    
  4. 等待元素可见:使用page.waitForSelector等待元素不仅出现在DOM中,而且是可见的:

    await page.waitForSelector(selector, { visible: true });
    
  5. 手动检查:在浏览器中手动检查页面,确认元素是否存在,以及是否有任何JavaScript错误。

  6. 调试截图:在等待选择器之前和之后添加截图,以帮助确定页面的实际状态:

    await page.screenshot({ path: 'before-wait.png' });
    await page.waitForSelector(selector);
    await page.screenshot({ path: 'after-wait.png' });
    
  7. 关闭浏览器:在调试完成后,记得关闭浏览器实例,以避免资源占用。

请根据实际情况调整代码,并确保在部署自动化脚本之前进行充分的测试。

pypeteer参数简介:

  • ignoreHTTPSErrors(bool):是否忽略 HTTPS 错误。默认值为 。False
  • headless(bool):是否在无头模式下运行浏览器。默认值为 unless 或 options 为 。True``appMode``devtools``True
  • executablePath(str):要运行的 Chromium 或 Chrome 可执行文件的路径 而不是默认捆绑的 Chromium。
  • slowMo(int|float):按指定的 毫秒数。
  • args(List[str]):要传递给浏览器的其他参数(标志) 过程。
  • ignoreDefaultArgs(bool):不要使用 pyppeteer 的默认参数。这 是危险的选择;小心使用。
  • handleSIGINT(bool):在 Ctrl+C 上关闭浏览器进程,默认为 。True
  • handleSIGTERM(bool):关闭 SIGTERM 上的浏览器进程。违约 自。True
  • handleSIGHUP(bool):关闭 SIGHUP 上的浏览器进程。默认值为 。True
  • dumpio(bool):是否通过管道传输浏览器进程 stdout 和 stderr into 和 .默认值为 。process.stdout``process.stderr``False
  • userDataDir(str):用户数据目录的路径。
  • env(dict):指定对 浏览器。默认值与 python 进程相同。
  • devtools(bool):是否为每个选项卡自动打开 DevTools 面板。 如果此选项为 ,则将设置该选项。True``headless``False
  • logLevel(int|str):用于打印日志的日志级别。默认值为 根记录器。
  • autoClose(bool):脚本时自动关闭浏览器进程 完成。默认值为 。True
  • loop(异步。AbstractEventLoop):事件循环(实验性)。
  • appMode(bool):已弃用。
3、进阶使用

尝试模拟登录某BI大数据平台

const puppeteer = require('puppeteer');(async () => {const browser = await puppeteer.launch({headless:false});//默认运行在无头模式// const browser = await puppeteer.launch();const page = await browser.newPage();// await page.goto('https://www.kanxue.com/book-section_list-83.htm');//await page.screenshot({path: 'example.png'});await page.setViewport(viewport={'width':1536,'height':768})await page.goto('https://www.captainbi.com/amz_login.html');//先点击登录// let login_btn = await page.$('#loginform > div:nth-child(4) > button')// login_btn.click()
//   let login = await page.$('#header > div > nav > div.text-right.nav_user_item > a.login_btn')
//   login.click()// //用户名// let loginInput = await page.$('#account')// //密码// let pwdInput = await page.$('#password')// console.log(loginInput)//打印DOM节点信息// console.log(pwdInput)// 使用page.type输入节点信息,输入用户名await page.type('#username', '')  // 使用page.type输入节点信息,输入密码await page.type('#password', '')  await page.click('#submit')console.log('登录成功')//使用page方法获取用户名节点await browser.close();
})();
唯品会案例

品牌URL路径
在这里插入图片描述

//*[@id=“J_brand_sn_filter”]/div/div[1]/div/ul/li[1]/a

在这里插入图片描述

商品URL路径://*[@id=“J_searchCatList”]

(//*[@id=“J_searchCatList”]/div[2])

原价:

在这里插入图片描述

在这里插入图片描述

//*[@id=“J_searchCatList”]/div[2]/a/div[2]/div[1]/div/div[2]

总结规律后,换成更具有一般性的

.//[contains(@class,“c-goods-item__sale-price”)]/text()

运行报错

显示Empty DataFrame

发现是url_list为空
在这里插入图片描述

/html/body/div[2]/div[2]/div[1]/div[2]/div/div[1]/div/ul/li[1]/a

如果上述代码显示 “Empty DataFrame”,这可能是由于以下原因之一:

  1. XPath表达式不正确:如果提供的XPath表达式不匹配页面上的任何元素,那么 xpath() 方法将返回一个空列表。这意味着没有数据被提取,因此 DataFrame 保持为空。

  2. 页面结构变化:网站的页面结构可能已经发生了变化,导致原有的XPath表达式不再有效。网站的更新可能会改变元素的类名、ID或其他属性。

  3. 动态加载的内容:有些网页内容是通过JavaScript动态加载的。如果 pyppeteer 在页面内容加载完成之前就执行了 page.content(),那么可能会错过一些动态加载的数据。

  4. 网络或请求问题:网络问题或请求配置错误(如 headers、cookies)可能导致请求失败,从而没有获取到任何数据。

  5. 爬虫机制:一些网站有反爬虫机制,如果检测到爬虫行为,可能会返回空内容或错误页面。

为了调试这个问题,你可以采取以下步骤:

  • 检查网络响应:打印 res.textpage_html 来检查服务器的响应内容是否包含预期的数据。

  • 验证XPath表达式:使用浏览器的开发者工具验证XPath表达式是否能够正确匹配目标元素。

  • 等待动态内容加载:在使用 pyppeteer 获取页面内容之前,确保页面上的JavaScript有足够的时间执行。你可以使用 page.waitForSelector() 等待特定元素出现。

  • 检查反爬虫机制:检查是否有反爬虫机制在干扰你的请求,例如通过检查是否需要验证码、登录状态或其他验证。

  • 异常处理:在代码中添加异常处理来捕获可能的错误,并打印出有用的调试信息。

  • 逐步调试:逐步执行代码,检查每个步骤的输出,确定数据丢失的具体位置。

请注意,由于网站的结构和内容可能会不断变化,因此维护爬虫代码需要定期检查和更新以适应这些变化。

在这里插入图片描述
经过分析后,发现接口的响应信息之前是静态的,但是现在是动态的了。

分析时候的误区:之前以为网页源代码中的信息就是HTML信息。

能看到的节点信息,但在网页源代码中看不到,通常是因为这些节点是通过JavaScript动态生成并添加到DOM中的。这意味着当网页最初从服务器加载时,这些节点并不包含在HTML源代码中。只有在浏览器执行了网页上的JavaScript脚本之后,这些节点才被创建并插入到DOM中。

这种情况在现代网页开发中非常常见,特别是在使用Ajax、Angular、React、Vue等JavaScript框架和库的网站上。这些技术允许网页在不重新加载整个页面的情况下,动态地更新和显示内容。

主要原因:

  1. 异步数据加载:网页可能在加载后,使用Ajax请求从服务器获取数据,然后使用JavaScript处理这些数据并更新DOM。
  2. 客户端渲染:网站可能使用客户端JavaScript框架进行内容渲染,这些框架在浏览器端创建HTML元素,并将它们动态添加到页面中。
  3. 用户交互:用户与页面的交互(如点击按钮、填写表单等)可能触发JavaScript函数,这些函数动态地在页面上创建或修改节点。

所以,虽然做错了,但是也知道了原因,之后尝试通过自动化请求的方式加载动态页面信息

使用pyppyteer动态获取数据

未完待续

相关文献资料:
Puppeteer自动化视频播放和模拟点击
  1. WebRTC视频流的自动化

    • 如何使用Puppeteer和Browserless自动化WebRTC视频流
    • 这篇文章展示了如何使用Puppeteer自动化WebRTC视频流的播放。
  2. Puppeteer浏览器自动化工具

    • PuppeteerSharp:基于原始Node库的C#库,提供高级API来控制浏览器
    • 这个视频介绍了Puppeteer的基本用法,包括如何使用Puppeteer进行浏览器自动化。
  3. Puppeteer无法点击视频的问题

    • 为什么Puppeteer无法点击视频
    • 这个Stack Overflow讨论涉及到Puppeteer无法点击视频播放按钮的问题,以及可能的解决方案。
  4. 使用无头浏览器进行网络爬虫:Puppeteer教程

    • 使用无头浏览器Puppeteer进行网络爬虫
    • 这篇文章展示了如何使用Puppeteer进行网络爬虫,包括模拟用户行为。
  5. 使用Puppeteer将视频流传输到Node.js缓冲区

    • 使用Puppeteer将流传输到Node.js缓冲区
    • 这个讨论涉及到如何使用Puppeteer获取视频流,并将其传输到Node.js缓冲区。
  6. 使用Puppeteer录制视频

    • 如何使用Puppeteer快速录制视频
    • 这篇博客文章介绍了如何使用Puppeteer的屏幕录制功能来录制视频,以及这种方法的优缺点。
  7. 自动化YouTube观看量

    • 自动化YouTube观看量的目的
    • 这篇文章探讨了使用自动化工具提高YouTube视频观看量的策略。

请注意,使用Puppeteer进行自动化操作时,要确保遵守所有相关的法律和网站条款。希望这些资源能帮助你开始使用Puppeteer进行视频播放和模拟点击的自动化任务。

pyppyteer动态获取数据资料

以下是一些关于使用 pyppeteer 来爬取动态加载网站内容的教程和资源:

  1. Python爬虫:使用pyppeteer爬取动态加载的网站原创 - 这篇文章介绍了如何使用 pyppeteer 爬取动态加载的网站内容。

  2. 动态网页爬取:使用Selenium和Pyppeteer处理动态加载内容 - 这篇博客讲述了如何使用 Seleniumpyppeteer 处理动态加载的网页内容。

  3. Python爬虫:使用pyppeteer爬取动态加载的网站 - 本文讨论了如何使用 pyppeteer 以及 requestsBeautiful Soup 库来获取和解析网页内容。

  4. Python实战之数据表提取和下载自动化 - 这篇文章介绍了如何使用 Pyppeteer 库来提取动态渲染页面中的数据表并实现自动化下载。

  5. 使用Pyppeteer+Bs4完成一个爬虫爬取项目所需数据 - 这篇文章详细介绍了如何结合 PyppeteerBeautiful Soup 4 完成一个爬虫项目,用于爬取所需数据。

官网信息
官网信息

pyppeteer
github 地址:https://github.com/pyppeteer/pyppeteer
文档:https://pyppeteer.github.io/pyppeteer/reference.html

puppeteer

github 地址:https://github.com/puppeteer/puppeteer
中文文档:https://zhaoqize.github.io/puppeteer-api-zh_CN/#/
英文文档:https://pptr.dev/

未完待续


http://www.ppmy.cn/news/1461793.html

相关文章

【C -> Cpp】由C迈向Cpp (6):静态、友元和内部类

标题:【C -> Cpp】由C迈向Cpp (6):静态、友元和内部类 水墨不写bug (图片来源于网络) 目录 (一)静态成员 (二)友元 (三&#xff09…

STM32 HAL TM1637使用

TM1637属于一种带键盘扫描接口的LED(发光二极管显示器)驱动控制专用电路。 本文主要使用MCU是STM32 ,CubeMXKeil5进行开发,使用HAL库 简介:TM1637可以带动16个按键以及做数码管驱动 TM1637.C #include "TM163…

selenium实战

Selenium是一个用于自动化Web应用程序测试的工具,它支持多种编程语言,包括Python。以下是一些关于使用Selenium进行实战的要点: 环境搭建:首先需要安装Python环境,然后通过pip安装Selenium库以及对应的WebDriver。例如…

Java编程思想

面向对象编程(OOP)-CSDN博客 面向对象(OOP)的主要特点-CSDN博客 接口(Interface)和抽象类(Abstract Class)编程思想-CSDN博客 接口(Interface)和抽象类(Abstract Class)区别-CSDN博客 抽象类(Abstract Class)-CSDN博客 普通类和抽象类-CSDN博客 内部类编程思想-CSDN博客 …

如何解决Java 中的精度问题

在 Java 编程中,处理浮点数和超大整数时常常会遇到精度丢失和数值溢出的困扰。为了确保计算结果的精确性,尤其是在金融计算等对精度要求极高的场景中,我们需要使用 BigDecimal 和 BigInteger 类。本文将详细介绍浮点数精度丢失的原因、如何解…

Redis加入系统服务,开机自启

vi /etc/systemd/system/redis.service i [Unit] Descriptionredis-server Afternetwork.target [Service] Typeforking #使用(/usr/local/bin/redis-server)运行(/usr/local/src/redis-6.2.6/redis.conf) ExecStart/usr/local/…

903. 昂贵的聘礼[dijsktra堆优化版]

题目描述 年轻的探险家来到了一个印第安部落里。 在那里他和酋长的女儿相爱了,于是便向酋长去求亲。 酋长要他用 10000 个金币作为聘礼才答应把女儿嫁给他。 探险家拿不出这么多金币,便请求酋长降低要求。 酋长说:”嗯,如果你能够…

【Linux】Docker 安装部署 Nacos

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ 【Linux】Docker 安装部署 Nacos docker搜索na…