最近开发了一个项目,需要通过PHP生成指定URL的缩略图,做NodeJS开发的时候,我们可以使用Headless Chrome来实现这个需求,在PHP生态中,有一个 spatie/browsershot库,也可以调用Headless Chrome来生成网页缩略图。下面来简单记录一下这个库的使用方法和使用过程中遇到的问题。

安装、配置spatie/browsershot库

首先,我们需要使用 composer 来安装 spatie/browsershot,这个不必多说。安装完成后,就可以通过官方的文档来调用这个库中的类来生成缩略图了。下面是官方的示例代码:

use SpatieBrowsershotBrowsershot;

$browsershot = new Browsershot;
$browsershot->setNodeModulePath('/path/to/your/node_modules');
$browsershot->setNpmBinary('/path/to/your/npm');
$browsershot->setPuppeteerExecutablePath('/path/to/your/puppeteer_executable');

$browser_shot->url($site_url)
                         ->windowSize(1440, 2000)
                         ->fullPage()
                         ->setScreenshotType('jpeg', 80)
                         ->save($save_path);

看起来很简单是吧?如果真是这样,这篇文章就没有存在的必要了。除了配置好需要的路径和参数,要想成功运行上面示例代码中的功能,我们还需要开启一些PHP扩展、安装Node js,chromium 等依赖,以及一些chromium依赖的第三方库。

开启PHP proc_open,proc_get_status 函数

首先,我们需要开启 PHP 的 proc_open,proc_get_status 这两个函数,browsershot 库需要这两个函数来执行Node JS 命令并获取执行状态。

这两个函数在很多环境中默认是关闭的,找到php.ini, 启用这两个函数即可。

安装 Node JS 以及 Chromium 库

browsershot 库是调用 Node JS 环境中的 Headless Chrome 来实现截图功能的,所以我们也需要把 Chromium 库安装好。我使用的CentOS系统,通过下面的命令来安装 NodeJS和 Chromium 即可。

sudo dnf module install nodejs:18
sudo dnf install chromium

如果系统软件仓库没有提供 chromium,可以使用下面的命令来安装。

npm i puppeteer

安装好之后,我们需要把对应文件的路径记录下来,写到文章开头的代码里面。如果不确定 chromium 的安装路径,可以使用下面的命令查看。

node -e "console.log(require('puppeteer').executablePath())

这里需要注意:运行PHP的用户要有chromium bin 文件的执行权限才可以执行。

安装Chromium系统依赖

Chromium会依赖Linux操作系统中的一些库,我们需要把这些库也安装好,这样chromium才能正确运行。

sudo dnf install atk at-spi2-atk libdrm libXcomposite libXdamage libXrandr mesa-libgbm pango alsa-lib

或者

sudo apt install -y libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libgbm1 libxdamage1 libxrandr2 libasound2 libpangocairo-1.0-0 libpangoft2-1.0-0 libnss3 libxcomposite1 libxshmfence1 libxrender1 libxfixes3 libxkbcommon0

因为每个Linux环境都不尽相同,除了上面的依赖库,您的环境中可能还缺少其他库,如果上面的库安装好之后,browsershot 依赖运行不起来,看browsershot的报错一般可以看出来缺少什么库,安装上即可。

browsershot性能及使用建议

browsershot所执行的操作其实就是打开一个页面来截图,截图生成的速度肯定不会太快,根据我的测试,一个宽1440像素,高2500的网页,截图生成的时间为2-3之间。当然这个时间也跟网页的打开速度和服务器的整体性能有关。基于这个速度,我们使用browsershot肯定无法执行一些同步的截图生成操作,一般是提前生成好缩略图保存在服务器上,在需要的时候直接去调用生成好的图片就可以了。