最近开发了一个项目,需要通过PHP生成指定URL的缩略图,做NodeJS开发的时候,我们可以使用Headless Chrome来实现这个需求,在PHP生态中,有一个 spatie/browsershot库,也可以调用Headless Chrome来生成网页缩略图。下面来简单记录一下这个库的使用方法和使用过程中遇到的问题。
安装、配置spatie/browsershot库
首先,我们需要使用 composer 来安装 spatie/browsershot,这个不必多说。安装完成后,就可以通过官方的文档来调用这个库中的类来生成缩略图了。下面是官方的示例代码:
use Spatie\Browsershot\Browsershot;
$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肯定无法执行一些同步的截图生成操作,一般是提前生成好缩略图保存在服务器上,在需要的时候直接去调用生成好的图片就可以了。