轶哥博客

妄图改变世界的全栈程序员。

Node.js 网页截图服务 - 网页快照API

Puppeteer 是 Headless Chrome Node API。也就是谷歌将Chrome无头浏览模式的接口封装成Node.js的API。利用Puppeteer实现网页截图/网页快照服务是非常容易的。

webpage-capture是基于Puppeteer实现带权限认证(多APP授权)、配备消息队列管理的网页快照API。

源代码:https://github.com/yi-ge/webpage-capture
功能:可对百万级网页数据进行截图采集的API服务。
Swagger文档:https://capture.gapi.store/documentation

系统架构

webpage-capture是由hapi + Puppeteer + Kue + Redis + 七牛实现的网页截图服务。

hapiNode.js生态中高效的API框架。

使用方法

git clone https://github.com/yi-ge/webpage-capture.git

参考config-example.js编写config.js文件。

请确保服务器已经安装了Chromium。

推荐使用Forever进行进程守护,监控API运行状态。

npm i -g forever
forever start app.js

慎用pm2,此处使用pm2fork模式将导致Chromium无法唤起。

不要忘记启动Redis,推荐使用Docker运行Redis。

docker run --name redis -itd -m 200m --restart=always -p 6379:6379 redis:5.0.3 redis-server --bind 0.0.0.0 --protected-mode no --requirepass 密码

为了确保系统安全,即便服务运行在服务器内网,端口没有直接映射到外网,也请开启Redis的Auth功能。

Chrome截图方法

不用Puppeteer也能轻易实现网页的截图。例如打开Chrome开发者工具,执行(Mac下Shift+command+p打开命令执行)>capture screenshot命令即可快速得到当前页面的完整截图。

或者使用命令得到一张截图:

Mac:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --no-sandbox --disable-setuid-sandbox --headless --disable-gpu --window-size=1024x768 --screenshot https://www.wyr.me

Chromium(Linux)

chromium-browser --no-sandbox --disable-setuid-sandbox --headless --disable-gpu --window-size=1024x768 --screenshot https://www.wyr.me

执行后将在当前目录下生成screenshot.png文件。

这个方法也适用于检测当前服务器chromium-browser是否正常安装(适用于ARM平台,在Raspberry测试通过)。

Puppeteer实现截图

基于Puppeteer实现截图只需要以下几行代码。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
    page.setViewport({
    width: 1024,
    height: 768
  })
  await page.goto('https://example.com');
    await page.screenshot({
      type: 'jpeg',
      path: saveUrl,
      fullPage: true
  })

  await browser.close();
})();

如果需求简单、使用量不高,以上代码完全能满足使用。但是在大量快照需求的情况下,则需要加入消息队列来确保截图过程的稳定。webpage-capture则基于消息队列实现大任务处理。

在树莓派中使用 webpage-capture

使用Puppeteer进行网页快照是一件非常消耗服务器资源的事情,等同于在服务器端启动一个Chrome/Chromium浏览器,然后在Chrome浏览器中执行快照操作。同一时间启动多个Chrome浏览器是非常消耗内存的。

使用Raspberry来对付这个需求是非常划算。基于ARM平台的树莓派功耗低,而且这个需求对网络的要求很低,由于网页快照的操作通常都只关心结果,对快照速度的要求很低,不值得为了实现这个功能去购置大量的服务器进行并行操作。换句话说,我们可以将快照任务压入消息队列,让树莓派按排队顺序依次完成工作。

由于目前(2019年01月13日)树莓派APT仓库中的Chromuim浏览器版本较低,使用Puppeteer会报错。因此需要从Ubuntu ARM仓库中下载最新版的Chromium进行安装。

https://launchpad.net/ubuntu/xenial/armhf/chromium-browser/71.0.3578.80-0ubuntu0.16.04.1
http://launchpadlibrarian.net/400387012/chromium-browser_71.0.3578.80-0ubuntu0.16.04.1_armhf.deb
http://launchpadlibrarian.net/400387014/chromium-codecs-ffmpeg-extra_71.0.3578.80-0ubuntu0.16.04.1_armhf.deb

下载上述三个文件,使用dpkg -i命令进行安装。

安装完成后使用命令进行测试。

chromium-browser --no-sandbox --disable-setuid-sandbox --headless --disable-gpu --window-size=1024x768 --screenshot https://www.wyr.me

如果命令测试得到正常的网页快照图片,说明Chromium浏览器安装成功且可以正常运行无头模式。

除此之外,webpage-capture在ARM环境(树莓派)中的使用与X64无异。

在Docker中运行webpage-capture?

目前webpage-capture暂时不支持在树莓派的Docker中运行。原因是Chromuim暂时没有合适的ARM镜像。可以参考https://github.com/DeinChristian/rpi-docker-selenium,基于selenium实现。

为快照任务添加权限认证

为了使整个系统简单轻量,webpage-capture使用Redis实现权限认证消息队列的所有操作。这也是webpage-captureurl-to-pdf-api很大的区别。

Application API

DELETE /application/del 删除 Application
POST /application/edit 添加/编辑 Application
GET /application/list 列出所有 Application

更多API使用说明见Swagger文档:https://capture.gapi.store/documentation

权限系统有一个超级密码,超级密码写入在config.js文件中。在进行Application API相关的所有操作,都需要超级密码。

例如,在POST /application/edit 添加/编辑 Application接口中传入下列数据:

[
  {
    "name": "土地应用"
  }
]

将得到该Application专属Token。进行快照相关的API操作时需要用到此Token

其它

webpage-capture系统中还有很多细节均在源码注释中说明,基于这个小程序还可以实现诸如Puppteer爬虫、网站运行状态监控等功能。

  上一篇 (Electron 预加载远程页面提升用户体验)
下一篇 (创业之殇——管理)