Headless Chrome打印PDF

lnxxn5zx  于 2023-04-27  发布在  Go
关注(0)|答案(8)|浏览(291)

我试图使用Chrome的Headless功能将HTML转换为PDF。然而,我根本没有得到输出。控制台也没有显示任何错误。我在Windows M/C中运行以下命令。
chrome --headless --disable-gpu --print-to-pdf
我尝试了所有的各种选项。没有任何正在生成。我有 chrome 版本60

6xfqseft

6xfqseft1#

命令行--print-to-pdf

默认情况下,--print-to-pdf尝试在用户目录中创建PDF。默认情况下,该用户目录是实际chrome二进制文件的存储位置,这是您正在运行的版本的特定版本文件夹-例如,“C:\Program Files(x86)\Google\Chrome\Application\61.0.3163.100”。并且,默认情况下... Chrome不允许写入此文件夹。您可以通过将--enable-logging添加到命令中来观察它的尝试和失败。
因此,不幸的是,默认情况下,此命令失败。*
你可以通过在参数中提供一个路径来解决这个问题,Chrome可以这样写

--print-to-pdf="C:\Users\Jane\test.pdf"

或者,您可以更改用户目录:

--user-data-dir="C:\Users\Jane"

您可能更喜欢更改用户目录的一个原因是,如果您希望PDF自动从网页接收其名称;Chrome查看标题标签,然后像<title>My Page</title> =〉My-Page.pdf一样转储它

  • 我认为这个默认行为非常令人困惑,应该作为Chrome的bug提交。然而,显然Chrome团队的一部分人完全反对这个命令行选项的存在,相反,他们认为最好强制每个使用它的人使用Puppeteer进行node.js构建,并彻底删除标志。

Windows下命令行的限制

以这种方式调用chrome可以很好地工作,例如在使用Visual Studio的IIS Express上的本地开发环境中,但是即使在运行IIS的服务器上,即使在无头模式下,它也会失败,因为IIS用户没有被赋予交互式/桌面权限,而chrome抓取此PDF的方式实际上需要交互式/桌面权限。提供这些权限的方法很复杂。但是任何地方你读到如何开始 * 不提供交互/桌面权限 *.此外,上述风险的Chrome有一天摆脱命令行使工作更加困难,让它工作一个不确定的命题.

chrome命令行的替代方法

wkhtmltopdf

从源代码来看,Chrome团队要么使用了wkhtmltopdf,要么基于wkhtmltopdf。我还没有尝试过,但这可能会完成工作。一个小风险是,在Chrome中制作PDF时,测试是显而易见的:在Chrome浏览器中查看页面。如果您感到紧张,请打开打印预览。在wkhtmltopdf中,它实际上是Chromium的不同版本,这可能会产生渲染差异。也许。正如社区用户指出的那样,wkhtmltopdf由所有者于2023年1月2日存档。

Selenium

另一种选择是赶在那些希望摆脱--print-to-pdf的人之前,使用他们喜欢的浏览器开发API(通过Selenium)。

private static void pdfSeleniumImpl(string url, string pdfPath)
{
    var options = new OpenQA.Selenium.Chrome.ChromeOptions();
    options.AddArgument("headless");

    using (var chrome = new OpenQA.Selenium.Chrome.ChromeDriver(options))
    {
        chrome.Url = url;

        var printToPdfOpts = new Dictionary<string, object>();
        var resultDict = (Dictionary<string, object>)
            chrome.ExecuteChromeCommandWithResult(
                "Page.printToPDF", printToPdfOpts);
        dynamic result = new DDict(resultDict);
        string data = result.data;
        var pdfFile = Convert.FromBase64String(data);
        System.IO.File.WriteAllBytes(pdfPath, pdfFile);
    }
}

上面的DDict是我的另一个答案中的GracefulDynamicDictionary。
https://www.nuget.org/packages/GracefulDynamicDictionary/
https://github.com/b9chris/GracefulDynamicDictionary
https://stackoverflow.com/a/24192518/176877
理想情况下,这将是异步的,因为所有对Selenium的调用实际上都是网络命令,并且写入该文件可能需要大量的磁盘IO。从Chrome返回的数据实际上也是一个Stream。然而遗憾的是,Selenium传统使用的库根本不使用异步,因此需要升级该库或为.Net确定一个可靠的异步Selenium库才能真正做到这一点。

任何基于Chrome的方法的限制

任何在服务器上使用Chrome的方法,包括Selenium,都必须处理Chrome的自动更新,以及需要更新的Selenium驱动程序以及构建的一部分。很少更新的代码如果没有科普策略,每3个月就会崩溃一次。
https://github.com/puppeteer/puppeteer/blob/master/lib/Page.js#L1007
https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF

**Page.pdf chrome Dev API命令也已弃用,因此如果该命令行获得成功,命令行和Dev API都将无法工作。也就是说,看起来那些游说破坏它的人2年前就放弃了。

mzsu5hc0

mzsu5hc02#

这是工作:

chrome --headless --disable-gpu --print-to-pdf=file1.pdf https://www.google.co.in/

在文件夹中创建文件:C:\Program Files (x86)\Google\Chrome\Application\61.0.3163.100 .

vfh0ocws

vfh0ocws3#

我在print-to-pdf命令后缺少“=”。

正确命令为:

chrome --headless --disable-gpu --print-to-pdf="C:/temp/name.pdf" https://www.google.com/

现在它起作用了。

ccrfmcuu

ccrfmcuu4#

扩展suraj的简单答案,我在我的源路径中创建了一个小函数,所以它像CLI工具一样工作:

function webtopdf(){
    chromium-browser --headless --disable-gpu --print-to-pdf=$2 $1
}

所以很快

webtopdf https://goo.com/some-article some-article.pdf

现在替我工作了

jm2pwxwz

jm2pwxwz5#

别忘了用管理员权限打开你的终端/cmd:)否则它根本不会保存文件。

avwztpqn

avwztpqn6#

这对我在windows工作
启动chrome --headless --disable-gpu --print-to-pdf= C:\Users\username\pdfs\chrome.pdf--no-margins https://www.google.com

gwbalxhn

gwbalxhn7#

对于Windows用户(以及其他使用MSEdge的用户),MSEdge提供了类似的功能-无头,此外版本III+具有“With Acrobat”渲染。
注意:Google Chromium使用不同的--switch!!=new --no-pdf-header-footer=old --print-to-pdf-no-header将headless更新为--headless=new和--headless=old
注意,在版本112中,Edge不考虑headless=new。
较新--交换机位于https://peter.sh/experiments/chromium-command-line-switches/
目前MSEdge使用--headless命令,就像--headless=old一样,因此仍然使用旧的-header语法,--headless --print-to-pdf-no-header也不会写入页脚。
没有必要设置配置文件,但您可以通过

"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --profile-directory=c:\whateverUneed --headless blah blah

应该没有必要使用任何GPU修补程序,这些都在Windows 5年前解决
因此,普通的日常命令可以是CWD是当前工作目录的任何路径

"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless=old  --print-to-pdf-no-header --print-to-pdf="c:\CWD\google.pdf" "https://google.com"

guz6ccqo

guz6ccqo8#

目前,这仅适用于Linux和Mac OS。

相关问题