6

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

 1 year ago
source link: https://www.wyr.me/post/606
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Node.js 网页截图服务

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文档: http://localhost:8080/documentation (需要先运行项目).

2023年3月12日更新: 近年来出现很多新的替代方案,此代码保持开源但不再更新。

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文档:http://localhost:8080/documentation (需要先运行项目)

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

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

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK