有些导航站提交网站后会把网站截图并且在详情页会附带网页截图,例如这个 博客大全:blogwe.com
挺好奇怎么实现的,所以了解到了这两个开源项目:Puppeteer 和 PuPHPeteer
注意:需要安装 NodeJs 8+ 的版本
设置 NodeJs 镜像(如果你是第一次安装 NodeJs):
npm config set registry https://registry.npm.taobao.org --global
安装 Puppeteer:
npm i puppeteer
安装 PuPHPeteer:
npm install @nesk/puphpeteer
为了方便实现功能和测试,使用了 Laravel 8 进行安装该项目。
安装 PuPHPeteer:
composer require nesk/puphpeteer
在 Laravel 8 安装 PuPHPeteer 后,创建一个控制器:
php artisan make:controller ImageController
在路由 web.php 中引入(这是 Laravel 8 的新特性):
use App\Http\Controllers\ImageController;
继续在路由写入:
Route::get('create_image', [ImageController::class, 'create']);
在控制器引入:
use Nesk\Puphpeteer\Puppeteer;
在控制器写入 create 方法后访问测试:
public function create()
{
$puppeteer = new Puppeteer;
$browser = $puppeteer->launch();
$page = $browser->newPage();
$page->goto('https://www.bubaijun.com');
$page->screenshot(['path'=>'example.png']);
$browser->close();
}
此时访问的页面是空白的,因为没有 return ,打开 public 目录可以看到有一个 example.png 文件,该文件如下:
1.png
可以看到图片尺寸有点小,可以将 create 方法改成这样:
public function create()
{
$puppeteer = new Puppeteer;
$browser = $puppeteer->launch();
$page = $browser->newPage();
$page->setViewport(['width' => 1920, 'height' => 1440]);
$page->goto('https://www.bubaijun.com');
$page->screenshot(['path' => 'example.png']);
$browser->close();
}
也就是在 newPage 方法后可以调用 setViewport 方法进行设置页面大小。
具体的相关文档:https://github.com/puppeteer/puppeteer/blob/main/README.md#usage
https://github.com/puppeteer/puppeteer/blob/v5.4.0/docs/api.md#pagesetviewportviewport
以上文档是 NodeJs 的,需要看懂后稍微修改在 PHP 进行调用。
最后说一下,截图所需的时间受影响的因素很多,所以最好放入队列运行。
截图的图片文件还挺大的,截图了一下 1920 * 1440 现在这个博客首页,图片文件是 916K. 可以适当使用一下压缩,博主用工具压缩后只有 344K.
截出来的图:
2.png