目录

nodejs实现网站截图接口

需求:通过一个网站链接获取网站的完整截图

接到需求的第一时间我就想到了puppeteer,然后直接就在我的node项目中开始开发,当下就遇到了很多问题

puppeteer安装失败

原因:puppeteer安装时会自动下载几百兆的chrome浏览器,所以很多时候会安装失败 解决办法:手动下载 Chrome 可执行文件,启动的时候指定chrome目录

step1:下载chrome

注意:mac、linux和windows分别对应不同的chrome版本,上面下载地址可以选择环境,我本机是windows,服务器是linux,所以下载了windows和linux

step2:修改chrome启动参数

本机调试的时候,把chrome解压到自己想要的目录下,然后修改启动参数,这里要注意:

  • windows和linux的chrome的可执行文件不一样,所以要记得区分一下
  • chrome路径一定不要写错,这里根据需要替换成自己存放chrome的路径
js 复制代码
// 获取chrome路径
export const getChromePath = () => {
  if (isDev()) {
    return 'D:/tools/chrome-win/chrome.exe'
  } else {
    return '/tools/chrome-linux/chrome'
  }
}

// 启动chrome,手动指定executablePath路径
const chromeFullPath = path.resolve(process.cwd(), getChromePath())
const browser = await puppeteer.launch({
  executablePath: chromeFullPath
})

const page = await browser.newPage()
await page.goto(url)

const screenshotDir = path.resolve(ROOT_PATH, 'screenshot')

if (!fs.existsSync(screenshotDir)) {
  fs.mkdirSync(screenshotDir)
}

const hash = crypto
  .createHash('md5')
  .update(`${url}_${Date.now()}`)
  .digest('hex')
await page.screenshot({
  fullPage: true,
  path: `${screenshotDir}/${hash}.jpg`
})
await browser.close()

return {
  msg: '截图成功',
  pic_name: `${hash}.jpg`
}

ok,现在可以截图了,但是又发现一个新的问题,网页中的图片是空白的

网页中的图片截取不全

原因:目前是一打开页面就直接截图,而网页图片加载是需要时间的,更何况还有的网址使用了图片懒加载,只渲染一屏内容

解决办法:让页面滚动到地步

js 复制代码
await page.goto(url)
// 滚动到页面底部,保证页面中图片都渲染出来
await page.evaluate(async () => {
  await new Promise((resolve) => {
    let totalHeight = 0
    const distance = 300
    const timer = setInterval(() => {
      const scrollHeight = document.body.scrollHeight
      window.scrollBy(0, distance)
      totalHeight += distance

      if (totalHeight >= scrollHeight) {
        clearInterval(timer)
        resolve('滚动完毕')
      }
    }, 100)
  })
})
...

ok,到这里就可以截到网站中的图片了,上面的100和300根据自己情况调整。

接下来就是往服务器部署了,把chrome-linux压缩包上传到服务器,解压到代码目录的上一层,然后启动服务,调用截图接口又发现问题

linux系统中启动chrome失败

报错信息: /data/apps/tools/chrome-linux/chrome: error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory

原因:linux环境运行chrome时需要安装一些依赖项

解决办法:

  • 进入chrome所在目录执行:ldd chrome | grep not,该命令会列出所有缺失的包
  • 然后安装所有缺失的包
    • 注意:这些包名有时候并不准确,会导致安装时找不到这些包
    • 因为不同的 Linux 发行版本可能使用不同的软件包管理工具和包名称
    • 这里我查看了下自己的发行版版本:lsb_release -a
    • 然后把发行版本信息提供给chatgpt,让gpt给我推荐了一下包名

我的服务器版本信息: 我的版本信息如下: LSB Version: :core-4.1-amd64:core-4.1-noarch Distributor ID: AlibabaCloud Description: Alibaba Cloud Linux release 3 (Soaring Falcon) Release: 3 Codename: SoaringFalcon

下载依赖包命令:

js 复制代码
sudo yum install atk at-spi2-atk libdrm libX11 libXcomposite libXdamage libXext libXfixes libXrandr libgbm pango cairo alsa-lib

ok,现在依赖项都安装好了,再次调用screenshot接口,又发现一个问题

禁用沙箱模式

原因:Chrome 默认情况下会尝试以沙箱模式运行,但在 root 用户下运行时,这可能会受到限制

解决办法:禁用沙箱模式

js 复制代码
// 启动chrome时添加一个参数,禁用沙箱模式
const browser = await puppeteer.launch({
    executablePath: chromeFullPath,
    args: ['--no-sandbox']
});

ok,改了代码重新发包部署后,接口终于通了,且能完美的截图了

注意:截的图片不要保存在项目目录中,否则使用pm2监听服务的话,会导致服务重启

这个问题是因为我测试功能时,把截的图片放到项目目录导致的,正常不会存到项目目录下

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
清岚_lxn7 分钟前
原生SSE实现AI智能问答+Vue3前端打字机流效果
前端·javascript·人工智能·vue·ai问答
ZoeLandia29 分钟前
Element UI 设置 el-table-column 宽度 width 为百分比无效
前端·ui·element-ui
橘子味的冰淇淋~1 小时前
解决 vite.config.ts 引入scss 预处理报错
前端·vue·scss
小小小小宇3 小时前
V8 引擎垃圾回收机制详解
前端
lauo3 小时前
智体知识库:ai-docs对分布式智体编程语言Poplang和javascript的语法的比较(知识库问答)
开发语言·前端·javascript·分布式·机器人·开源
拉不动的猪3 小时前
设计模式之------单例模式
前端·javascript·面试
一袋米扛几楼984 小时前
【React框架】什么是 Vite?如何使用vite自动生成react的目录?
前端·react.js·前端框架
Alt.94 小时前
SpringMVC基础二(RestFul、接收数据、视图跳转)
java·开发语言·前端·mvc
进取星辰4 小时前
1、从零搭建魔法工坊:React 19 新手村生存指南
前端·react.js·前端框架
前端开发张小七5 小时前
每日一练:2.leetcode回文数
前端·python