您现在的位置是:亿华云 > 数据库
用 Puppeteer 实现一个自动化机器人
亿华云2025-10-02 19:00:30【数据库】4人已围观
简介目录 简介Selenium vs Puppeteer安装一个简单的例子解释代码把项目容器化容器打包时的一些坑1. Puppeteer 安装 Chromium 时会缺少一些组件2. 页面焦
简介
Selenium vs Puppeteer
安装
一个简单的实现例子
解释代码
把项目容器化
容器打包时的一些坑
1. Puppeteer 安装 Chromium 时会缺少一些组件
2. 页面焦点问题
3. Page Crash 问题
4. 时区问题
Puppeteer 是 Node.js 的一个函数库,可用来操控浏览器,个自是动化 Google 的项目,可以应用的机器范围包括:前端的自动化测试、爬虫、实现表单提交等。个自
Selenium vs Puppeteer
之前有过用 Python 配合 Selenium 的动化经验,不过如果是机器做爬虫、自动化操作用 Puppeteer 还是实现非常方便的,安装简单快速,个自API 也容易使用。动化美中不足的机器是它只支持 Chromium 以下是两者的比较,仅供参考:
由于 Puppeteer 是实现用 Node.js 写的,所以必须要先安装 Node。个自
可以至官网 下载
如果用 mac 可以使用 https://nodejs.org/en/安装完后可以在 terminal 输入 node -v 检查是动化否安装成功
然后到要开发的源码库项目路径下输入 npm init -y 初始化项目,接着 npm i puppeteer ,安装的时候会发现它会连同 Chromium 一同安装。
安装成功后就可以开始了。
一个简单的例子
新增一个文件 main.js ,并复制以下代码:
const puppeteer = require(puppeteer); (async () => { // 开启 browser const browser = await puppeteer.launch({ headless: false }); // 新增分页 const page = await browser.newPage(); // 到自己的博客网站 await page.goto(`https://www.myblog.com/`); // 等待订阅按钮出现 await page.waitForSelector("button[class=subscribe-button pill-button]"); // 点击订阅按钮 await page.click("button[class=subscribe-button pill-button]"); })();接着到终端下输入 node main.js 执行。
解释代码
前面的代码先引入 Puppeteer,以便后续使用,接下来可以看到用 async 以及 () => , async 表示函数要用到异步操作, () => 则是 JS 的箭头函数。
const puppeteer = require(puppeteer);接下来是用 Puppeteer 打开一个浏览器 ( Chromium ),其中可以看到我们设了参数 headless : false ,如果是设定为 true ,会开启没有界面的无头浏览器,如果设定 false ,就会开一个浏览器窗口。
const browser = await puppeteer.launch({ headless: false });这段就很简单了,它会帮你在浏览器开一个新的分页。
const page = await browser.newPage();这段也很容易,看到 goto 就可以猜到会帮你导向后方指定的网址。
await page.goto(`https://b123105.blogspot.com/`);最后这段代码用到了 click 这个方法,站群服务器它能够帮你点击后面指定的元素,可以看到我是指定 class = subscribe-button pill-button 的 <button> 。
waitForSelector 的作用是,在执行时整个操作速度会很快,有时可能这个元素都很没出现,就让它去点击,有可能会找不到。所以先让它等待指定元素出现后,再去点击。
await page.waitForSelector("button[class=subscribe-button pill-button]"); await page.click("button[class=subscribe-button pill-button]");把项目容器化
首先下载 Docker,这里就不再赘述。接下来在项目目录下创建 Dockerfile ,把下面的脚本代码复制粘贴。
然后构建镜像: docker build -t puppeteer-bot . 。
构建完成后就执行 docker run -d --name puppeteer-bot-timeline puppeteer-bot:latest 。
之后可以通过 docker logs puppeteer-bot-timeline 查看 console.log 的内容 ( 如果有的话 )。
要记得 headless 要设定为 true 才能运行。 FROM node:11-slim # 下载 chromium 在 docker 运行时所需组件 RUN apt-get update && apt-get install -yq libgconf-2-4 RUN apt-get update && apt-get install -y wget --no-install-recommends \ && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ && sh -c echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list \ && apt-get update \ && apt-get install -y google-chrome-unstable \ --no-install-recommends \ && rm -rf /var/lib/apt/lists/* \ && apt-get purge --auto-remove -y curl \ && rm -rf /src/*.deb ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 /usr/local/bin/dumb-init RUN chmod +x /usr/local/bin/dumb-init USER root ENV TZ=Asia/Shanghai # 转换时区,非必要 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone COPY . /app/ WORKDIR app RUN npm install EXPOSE 8084 ENTRYPOINT ["dumb-init", "--"] CMD ["node", "main.js"]容器打包时的一些坑
接下来是我在用 Docke 打包过程遇到的一些问题:
1. Puppeteer 安装 Chromium 时会缺少一些组件
本来用 docker 封装是很容易的,安装 node 然后 npm install 就行了,云服务器提供商但是在实际操作时一直报错说 Chromium 缺少组件。后来去 Puppeteer 的 issue 上查到原来安装 Puppeteer 时会自动安装 Chromium,但要在 Docker 上运行的相关组件并不会自动下载。
2. 页面焦点问题
在开发时我是通过开启一个浏览器,然后持续开三个分页来进行操作,希望能加快处理的速度。但是发现当 headless:false 时,会同时开启三个分页,但只有被设置为焦点的当前页面在执行后面的脚本,另外两页并没有。因为在开发过程中执行时 tab 页会被关闭,所以接下来第二个 tab 中的页面获得焦点后会再开始运行。
在 issue 中也看到有人遇到了同样的问题,只有在 headless:true 的时候会同时处理,但目前还没找到其他解法。
3. Page Crash 问题
上面有提到我在一个浏览器上操作三个分页,放在 docker 中运行,总是遇到 Page Crash 问题,第一反应是可能内存不足,在 issue 上查到原来在打开浏览器时要加上 --disable-dev-shm-usage 。
原文是这样说的:
By default, Docker runs a container with a /dev/shm shared memory space 64MB. This is typically too small for Chrome and will cause Chrome to crash when rendering large pages. To fix, run the container with docker run --shm-size=1gb to increase the size of /dev/shm. Since Chrome 65, this is no longer necessary. Instead, launch the browser with the --disable-dev-shm-usage flag: const browser = await puppeteer.launch({ args: [--disable-dev-shm-usage] });
4. 时区问题
这个问题与 Puppeteer 无关,有的服务器时区默认是 GMT,这时就要在 Dockerfile 指定容器的时区,不然代码中涉及到时间的操作时会被自动加 8 小时。
很赞哦!(913)