stomaskov / browsershot
使用无头Chrome将网页转换为图片或PDF
Requires
- php: ^7.4|^8.0
- spatie/image: ^1.5.3
- spatie/temporary-directory: ^1.1
- symfony/process: ^5.0
Requires (Dev)
- phpunit/phpunit: ^9.0
- spatie/phpunit-snapshot-assertions: ^4.2.3
- dev-master
- 3.41.2
- 3.41.1
- 3.41.0
- 3.40.3
- 3.40.2
- 3.40.1
- 3.40.0
- 3.39.0
- 3.38.0
- 3.37.2
- 3.37.1
- 3.37.0
- 3.36.0
- 3.35.0
- 3.34.0
- 3.33.1
- 3.33.0
- 3.32.2
- 3.32.1
- 3.32.0
- 3.31.1
- 3.31.0
- 3.30.0
- 3.29.0
- 3.27.0
- 3.26.3
- 3.26.2
- 3.26.1
- 3.26.0
- 3.25.1
- 3.25.0
- 3.24.0
- 3.23.1
- 3.23.0
- 3.22.1
- 3.22.0
- 3.20.1
- 3.20.0
- 3.19.0
- 3.18.0
- 3.17.0
- 3.16.1
- 3.16.0
- 3.15.0
- 3.14.1
- 3.14.0
- 3.13.0
- 3.12.0
- 3.11.1
- 3.11.0
- 3.10.0
- 3.9.0
- 3.8.1
- 3.8.0
- 3.7.0
- 3.6.0
- 3.5.0
- 3.4.0
- 3.3.1
- 3.3.0
- 3.2.1
- 3.2.0
- 3.1.0
- 3.0.0
- v2.x-dev
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.0
- 2.2.0
- 2.1.0
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 1.9.1
- 1.9.0
- 1.8.0
- 1.7.0
- 1.6.0
- 1.5.4
- 1.5.3
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.0
- 1.3.0
- 1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.0
- 1.0.0
- 0.1.3
- 0.1.2
- 0.1.1
- 0.1.0
- dev-github-actions
This package is not auto-updated.
Last update: 2024-09-21 07:54:49 UTC
README
使用无头Chrome将网页转换为图片或PDF
此包可以将网页转换为图片或PDF。转换过程由Puppeteer在幕后完成,它控制着Google Chrome的无头版本。
以下是一个快速示例
use Spatie\Browsershot\Browsershot; // an image will be saved Browsershot::url('https://example.com')->save($pathToImage);
如果传递给save
方法的路径有pdf
扩展名,它将保存PDF。
// a pdf will be saved Browsershot::url('https://example.com')->save('example.pdf');
您还可以使用任意的HTML输入,只需将url
方法替换为html
Browsershot::html('<h1>Hello world!!</h1>')->save('example.pdf');
Browsershot还可以在JavaScript执行后获取HTML页面的主体
Browsershot::url('https://example.com')->bodyHtml(); // returns the html of the body
如果您希望获取页面触发的所有请求的数组列表,您可以这样做
$requests = Browsershot::url('https://example.com') ->triggeredRequests(); foreach ($requests as $request) { $url = $request['url']; //https://example.com/ }
triggeredRequests()
与此处所述的waitUntilNetworkIdle
一起工作得很好
支持我们
我们投入了大量资源来创建一流的开放式源代码包。您可以通过购买我们的付费产品之一来支持我们。
我们非常感谢您从家乡寄给我们明信片,说明您正在使用我们的哪个包。您可以在我们的联系页面上找到我们的地址。我们将所有收到的明信片发布在我们的虚拟明信片墙上。
要求
此包需要node 7.6.0或更高版本以及Puppeteer Node库。
在MacOS上,您可以通过NPM在项目中安装Puppeteer
npm install puppeteer
或者您可以选择全局安装它
npm install puppeteer --global
在由Forge配置的Ubuntu 16.04服务器上,您可以像这样安装最新稳定版本的Chrome
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt-get install -y nodejs gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget libgbm-dev
sudo npm install --global --unsafe-perm puppeteer
sudo chmod -R o+rx /usr/lib/node_modules/puppeteer/.local-chromium
自定义node和npm二进制文件
根据您的设置,node或npm可能不是直接可用的Browsershot。如果您需要手动设置这些二进制文件路径,您可以通过调用setNodeBinary
和setNpmBinary
方法来完成。
Browsershot::html('Foo')
->setNodeBinary('/usr/local/bin/node')
->setNpmBinary('/usr/local/bin/npm');
默认情况下,Browsershot将使用node
和npm
来执行命令。
自定义包含路径
如果您不想手动指定二进制文件路径,而是要修改一般的包含路径,您可以使用setIncludePath
方法来设置它。
Browsershot::html('Foo') ->setIncludePath('$PATH:/usr/local/bin')
设置包含路径在以下情况下可能很有用:无法自动找到node
和npm
。
自定义node模块路径
如果您想使用替代的node_modules
源,您可以使用setNodeModulePath
方法来设置它。
Browsershot::html('Foo') ->setNodeModulePath("/path/to/my/project/node_modules/")
自定义二进制文件路径
如果您想使用替代的脚本源,您可以使用setBinPath
方法来设置它。
Browsershot::html('Foo') ->setBinPath("/path/to/my/project/my_script.js")
自定义chrome/chromium可执行文件路径
如果您想使用Puppeteer安装的替代chrome或chromium可执行文件,您可以使用setChromePath
方法来设置它。
Browsershot::html('Foo') ->setChromePath("/path/to/my/chrome")
向Chromium传递自定义参数
如果您需要向Chromium传递自定义参数,请使用addChromiumArguments
方法。
该方法接受键/值对的数组,或者简单地值。所有这些参数都将自动以--
为前缀。
Browsershot::html('Foo') ->addChromiumArguments([ 'some-argument-without-a-value', 'keyed-argument' => 'argument-value', ]);
如果没有提供键,则将参数按原样传递。
此方法在传递标志以解决某些Linux发行版(例如CentOS)中的字体渲染问题时可能很有用。
Browsershot::html('Foo') ->addChromiumArguments([ 'font-render-hinting' => 'none', ]);
安装
此包可以通过Composer安装。
composer require spatie/browsershot
使用方法
在所有示例中,假设您已将此命名空间导入到文件顶部。
use Spatie\Browsershot\Browsershot;
屏幕截图
这是创建网页图像的最简单方法。
Browsershot::url('https://example.com')->save($pathToImage);
图像格式化
默认情况下,截图的类型将是 png
。 (根据 Puppeteer 配置) 但您可以通过质量选项将其更改为 jpeg
。
Browsershot::url('https://example.com') ->setScreenshotType('jpeg', 100) ->save($pathToImage);
图像尺寸
默认情况下,截图的大小将与您桌面使用的分辨率匹配。想要其他尺寸的截图?没问题!
Browsershot::url('https://example.com') ->windowSize(640, 480) ->save($pathToImage);
您还可以独立于窗口大小设置输出图像的大小。以下是如何将分辨率为1920x1080的截图调整大小到200x200内。
Browsershot::url('https://example.com') ->windowSize(1920, 1080) ->fit(Manipulations::FIT_CONTAIN, 200, 200) ->save($pathToImage);
您可以使用 clip
仅捕获页面的一部分。
Browsershot::url('https://example.com') ->clip($x, $y, $width, $height) ->save($pathToImage);
您可以使用 select
捕获匹配选择器的元素。
Browsershot::url('https://example.com') ->select('.some-selector') ->save($pathToImage);
获取base64格式的截图
如果您需要截图的base64版本,可以使用 base64Screenshot
方法。这在您不想将截图保存到磁盘时非常有用。
$base64Data = Browsershot::url('https://example.com') ->base64Screenshot();
图像处理
您可以使用 spatie/image 提供的所有方法。以下是一个创建灰度图像的示例。
Browsershot::url('https://example.com') ->windowSize(640, 480) ->greyscale() ->save($pathToImage);
全页截图
您可以使用 fullPage()
方法捕获页面的全部长度。
Browsershot::url('https://example.com') ->fullPage() ->save($pathToImage);
设置设备缩放
您还可以通过传递2或3的设备缩放因子值来以更高的像素密度捕获网页。这模仿了网页在视网膜/xhdpi显示屏上的显示方式。
Browsershot::url('https://example.com') ->deviceScaleFactor(2) ->save($pathToImage);
移动仿真
您可以使用 mobile
和 touch
方法来仿真移动视图。 mobile
将设置显示以考虑页面的meta viewport,就像Chrome移动浏览器一样。 touch
将设置浏览器仿真触摸功能,从而允许对检查触摸的页面进行欺骗。结合 userAgent
方法,这些方法可以有效地捕获页面的移动截图。
Browsershot::url('https://example.com') ->userAgent('My Mobile Browser 1.0') ->mobile() ->touch() ->save($pathToImage);
设备仿真
您可以使用 device
方法来仿真设备视图。设备的名称可以在 此处 找到。
$browsershot = new Browsershot('https://example.com', true); $browsershot ->device('iPhone X') ->save($pathToImage);
等同于
Browsershot::url('https://example.com') ->userAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1') ->windowSize(375, 812) ->deviceScaleFactor(3) ->mobile() ->touch() ->landscape(false) ->save($pathToImage);
背景
如果您在捕获截图时想忽略网站的背景,请使用 hideBackground()
方法。
Browsershot::url('https://example.com') ->hideBackground() ->save($pathToImage);
关闭对话框
JavaScript 弹出窗口,如警告、提示和确认,会导致站点渲染停止,从而导致截图为空。调用 dismissDialogs()
方法会自动关闭此类弹出窗口,以便进行截图。
Browsershot::url('https://example.com') ->dismissDialogs() ->save($pathToImage);
禁用JavaScript
如果您在捕获页面时想完全禁用JavaScript,请使用 disableJavascript()
方法。请注意,某些站点在没有JavaScript的情况下可能无法正确渲染。
Browsershot::url('https://example.com') ->disableJavascript() ->save($pathToImage);
禁用图像
您可以使用 disableImages()
方法在捕获页面时完全删除所有图像和 元素。
Browsershot::url('https://example.com') ->disableImages() ->save($pathToImage);
阻止URL
您可以使用 blockUrls()
方法完全阻止连接到特定URL。这对于阻止广告和跟踪器以加快截图创建速度非常有用。
$urlsList = array("example.com/cm-notify?pi=outbrain", "sync.outbrain.com/cookie-sync?p=bidswitch"); Browsershot::url('https://example.com') ->blockUrls($urlsList) ->save($pathToImage);
阻止域名
您可以使用 blockDomains()
方法完全阻止连接到特定域名。这对于阻止广告和跟踪器以加快截图创建速度非常有用。
$domainsList = array("googletagmanager.com", "googlesyndication.com", "doubleclick.net", "google-analytics.com"); Browsershot::url('https://example.com') ->blockDomains($domainsList) ->save($pathToImage);
等待懒加载资源
一些网站通过Ajax或使用webfonts懒加载额外资源,这可能导致截图时资源未能及时加载。使用waitUntilNetworkIdle()
方法,您可以告诉Browsershot在截图前等待500毫秒,期间没有网络活动,以确保所有额外资源都已加载。
Browsershot::url('https://example.com') ->waitUntilNetworkIdle() ->save($pathToImage);
或者,您可以使用不太严格的waitUntilNetworkIdle(false)
,在500毫秒的等待期内允许2个网络连接,这对于脚本定期ping Ajax端点的网站很有用。
延迟截图
您可以使用setDelay()
延迟截图。如果您需要等待JavaScript完成或尝试捕获懒加载的资源,这很有用。
Browsershot::url('https://example.com') ->setDelay($delayInMilliseconds) ->save($pathToImage);
等待JavaScript函数
您还可以使用waitForFunction()
等待JavaScript函数直到返回true。如果您需要等待与网络状态无关的JavaScript任务,这很有用。
Browsershot::url('https://example.com') ->waitForFunction('window.innerWidth < 100', $pollingInMilliseconds, $timeoutInMilliseconds) ->save($pathToImage);
添加JS
您可以使用Puppeteer的addScriptTag
语法在截图或输出之前添加JavaScript,具体可参考Puppeteer的addScriptTag。
Browsershot::url('https://example.com') ->setOption('addScriptTag', json_encode(['content' => 'alert("Hello World")'])) ->save($pathToImage);
添加CSS
您可以使用Puppeteer的addStyleTag
语法在截图或输出之前添加CSS样式,具体可参考Puppeteer的addStyleTag。
Browsershot::url('https://example.com') ->setOption('addStyleTag', json_encode(['content' => 'body{ font-size: 14px; }'])) ->save($pathToImage);
直接输出到浏览器
您可以使用screenshot()
方法将图像直接输出到浏览器。
$image = Browsershot::url('https://example.com') ->screenshot()
PDFs
如果传递给save
方法的路径有pdf
扩展名,Browsershot将保存PDF。
// a pdf will be saved Browsershot::url('https://example.com')->save('example.pdf');
或者,您可以显式使用savePdf
方法
Browsershot::url('https://example.com')->savePdf('example.pdf');
您还可以传递一些HTML,这些HTML将被转换为PDF。
Browsershot::html($someHtml)->savePdf('example.pdf');
设置PDF大小
您可以指定宽度和高度。
Browsershot::html($someHtml) ->paperSize($width, $height) ->save('example.pdf');
可选地,您可以将自定义单位作为第三个参数传递给paperSize
。
使用预定义格式
您可以使用format
方法并提供格式大小
Browsershot::html('https://example.com')->format('A4')->save('example.pdf');
Puppeteer提供的format
选项
Letter: 8.5in x 11in Legal: 8.5in x 14in Tabloid: 11in x 17in Ledger: 17in x 11in A0: 33.1in x 46.8in A1: 23.4in x 33.1in A2: 16.54in x 23.4in A3: 11.7in x 16.54in A4: 8.27in x 11.7in A5: 5.83in x 8.27in A6: 4.13in x 5.83in
设置边距
可以设置边距。
Browsershot::html($someHtml) ->margins($top, $right, $bottom, $left) ->save('example.pdf');
可选地,您可以将自定义单位作为第五个参数传递给margins
。
页眉和页脚
默认情况下,PDF不会显示由Chrome生成的页眉和页脚。以下是使页眉和页脚出现的方法。您还可以提供自定义HTML模板作为页眉和页脚。
Browsershot::html($someHtml) ->showBrowserHeaderAndFooter() ->headerHtml($someHtml) ->footerHtml($someHtml) ->save('example.pdf');
在页眉和页脚HTML中,以下类别的任何标签都将将其打印值注入到其内容中。
date
格式化打印日期title
文档标题url
文档位置pageNumber
当前页码totalPages
文档中的总页数
要隐藏页眉或页脚,您可以调用hideHeader
或hideFooter
。
背景
默认情况下,生成的PDF不会显示HTML页面的背景。如果您希望包含背景,可以调用showBackground
。
Browsershot::html($someHtml) ->showBackground() ->save('example.pdf');
横版方向
如果您希望生成的PDF为横版方向,请调用landscape
。
Browsershot::html($someHtml) ->landscape() ->save('example.pdf');
仅导出特定页面
您可以通过将打印范围传递给pages
方法来控制应导出哪些页面。以下是一些有效的打印范围示例:1
、1-3
、1-5, 8, 11-13
。
Browsershot::html($someHtml) ->pages('1-5, 8, 11-13') ->save('example.pdf');
直接输出到浏览器
您可以使用pdf()
方法将PDF直接输出到浏览器。
$pdf = Browsershot::url('https://example.com') ->pdf()
HTML
Browsershot还可以在JavaScript执行后获取HTML页面的主体
Browsershot::url('https://example.com')->bodyHtml(); // returns the html of the body
评估
Browsershot可以获取HTML页面的评估结果
Browsershot::url('https://example.com') ->deviceScaleFactor(2) ->evaluate("window.devicePixelRatio"); // returns 2
其他
设置任意选项
您可以通过调用setOption
设置任何任意选项
Browsershot::url('https://example.com') ->setOption('landscape', true) ->save($pathToImage);
修复cors问题
如果您遇到与cors相关的问题,您可以选择使用--disable-web-security禁用cors检查。
Browsershot::url('https://example.com') ->setOption('args', ['--disable-web-security']) ->save($pathToImage);
更改浏览器的语言
您可以使用setOption
更改浏览器的语言。例如,为了加载特定语言的页面。
Browsershot::url('https://example.com') ->setOption('args', '--lang=en-GB') ...
设置用户代理
如果您想设置Google Chrome在截图时使用的用户代理,您可以这样做。
Browsershot::url('https://example.com') ->userAgent('My Special Snowflake Browser 1.0') ->save($pathToImage);
设置页面的CSS媒体类型
您可以使用媒体类型进行模拟,这在生成PDF截图时特别有用,因为它将默认尝试模拟页面的打印版。
Browsershot::url('https://example.com') ->emulateMedia('screen') // "screen", "print" (default) or null (passing null disables the emulation). ->savePdf($pathToPdf);
Browsershot的默认超时设置为60秒。当然,您可以修改此超时。
Browsershot::url('https://example.com') ->timeout(120) ->save($pathToImage);
禁用沙盒
在特定虚拟化环境中运行Linux时,可能需要禁用沙盒。
Browsershot::url('https://example.com') ->noSandbox() ...
忽略HTTPS错误
如果需要,您可以忽略HTTPS错误。
Browsershot::url('https://example.com') ->ignoreHttpsErrors() ...
指定代理服务器
您可以在连接时指定一个代理服务器。传递给setProxyServer
的参数将被传递到Chromium的--proxy-server=
选项。更多信息请参阅:https://www.chromium.org/developers/design-documents/network-settings#TOC-Command-line-options-for-proxy-settings
Browsershot::url('https://example.com') ->setProxyServer("1.2.3.4:8080") ...
设置额外的HTTP头
要发送自定义HTTP头,请设置extraHTTPHeaders选项,如下所示。
Browsershot::url('https://example.com') ->setExtraHttpHeaders(['Custom-Header-Name' => 'Custom-Header-Value']) ...
使用HTTP身份验证
您可以为HTTP身份验证提供凭据。
Browsershot::url('https://example.com') ->authenticate('username', 'password') ...
使用Cookies
您可以在请求给定的URL时添加Cookies。
Browsershot::url('https://example.com') ->useCookies(['Cookie-Key' => 'Cookie-Value']) ...
如果需要,您可以指定将Cookies注册到的域。
Browsershot::url('https://example.com') ->useCookies(['Cookie-Key' => 'Cookie-Value'], 'ui.example.com') ...
点击页面
您可以指定页面上的点击。
Browsershot::url('https://example.com') ->click('#selector1') // Right click 5 times on #selector2, each click lasting 200 milliseconds. ->click('#selector2', 'right', 5, 200)
在页面上输入
您可以在页面上输入(您可以使用此功能填写表单字段)。
Browsershot::url('https://example.com') ->type('#selector1', 'Hello, is it me you are looking for?')
您可以将type
和click
结合起来,在提交表单后创建页面的截图。
Browsershot::url('https://example.com') ->type('#firstName', 'My name') ->click('#submit') ->delay($millisecondsToWait) ->save($pathToImage);
更改下拉列表的值
您可以在页面上更改下拉列表的值(您可以使用此功能更改表单选择字段)。
Browsershot::url('https://example.com') ->selectOption('#selector1', '100')
您可以将selectOption
、type
和click
结合起来,在提交表单后创建页面的截图。
Browsershot::url('https://example.com') ->type('#firstName', 'My name') ->selectOption('#state', 'MT') ->click('#submit') ->delay($millisecondsToWait) ->save($pathToImage);
将选项写入文件
当传递给Puppeteer的选项数量太大时,Browsershot将由于命令行字符溢出而失败。Browsershot可以将选项写入文件,并将该文件传递给Puppeteer,从而绕过字符溢出。
Browsershot::url('https://example.com') ->writeOptionsToFile() ...
连接到远程chromium/chrome实例
如果您有一个已正确配置了--remote-debugging-port参数的远程chromium/chrome实例的端点,您可以使用setRemoteInstance
方法连接到它。您只需指定其IP地址和端口号(默认分别为127.0.0.1和9222)。如果给定的端点没有可用的实例(实例崩溃、重启实例等),这将回退到启动chromium实例。
Browsershot::url('https://example.com') ->setRemoteInstance('1.2.3.4', 9222) ...
使用管道而不是WebSocket
如果您想通过管道而不是WebSocket连接到浏览器,您可以使用
Browsershot::url('https://example.com') ->usePipe() ...
将环境变量传递给浏览器
如果您想设置影响浏览器实例的自定义环境变量,您可以使用
Browsershot::url('https://example.com') ->setEnvironmentOptions(['TZ' => 'Pacific/Auckland']) ...
相关包
- Laravel包装器:laravel-browsershot
贡献
有关详细信息,请参阅CONTRIBUTING。
安全
如果您发现任何安全相关的问题,请通过电子邮件freek@spatie.be报告,而不是使用问题跟踪器。
替代方案
如果您无法安装Node和Puppeteer,请查看browsershot的第2版(v2),该版本使用Chrome无头CLI进行截图。请注意,v2
已不再维护,但应该运行得相当不错。
如果无头Chrome对您不起作用,请查看此包的v1
版本,该版本使用废弃的PhantomJS
二进制文件。
鸣谢
特别感谢Caneco为我们提供的标志 ✨
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件。