【问题标题】:How to run Headless Chrome in Azure Cloud Service or Azure Functions?如何在 Azure 云服务或 Azure Functions 中运行 Headless Chrome?
【发布时间】:2017-12-14 04:52:09
【问题描述】:

我正在尝试使用 Headless Chrome 从复杂的 HTML 文件(包含图像、SVG 等)生成 PDF 文件。我可以在云服务(Windows)上使用 wkhtmltopdf.exe 来生成简单的 PDF 文件,但我真的需要 Chrome 来生成尽可能接近 HTML + SVG + 图像的 PDF。

我希望能够在 Azure 云服务或 Azure Functions 中运行 Headless Chrome,但我无法让它工作。我想这是由于对 GDI 的限制。我能够在我自己的机器上的 Azure 模拟器中运行我的代码和 Headless Chrome,但是一旦部署它就没有任何效果。

以下是我目前在 Azure Functions(适用于 Windows)中运行的代码。我正在使用 Puppeteer 截取 example.com 的屏幕截图。如果我能做到这一点,我想生成 PDF 会变得容易。

const fs = require('fs');
const path = require('path');
const puppeteer = require('puppeteer');
const os = require('os');

module.exports = function (context, req) {
    function failureCallback(error) {
        context.log("--> Failure = '" + error + "'");
    }

    const chromeDir = path.normalize(__dirname + "/../node_modules/puppeteer/.local-chromium/win64-508693/chrome-win32/chrome.exe");
    context.log("--> Chrome Path = " + chromeDir);

    const dir = path.join(os.tmpdir(), '/screenshots');

    if (!fs.existsSync(dir)){
        fs.mkdirSync(dir);
    }

    const screenshotPath = path.join(dir, "example.png");
    context.log("--> Path = " + screenshotPath);

    let browser, page;
    puppeteer.launch({ executablePath: chromeDir, headless: true, args: [ '--no-sandbox', '--single-process', '--disable-gpu' ] })
        .then(b => {
            context.log("----> 1");
            browser = b;
            return browser.newPage();
        }, failureCallback)
        .then(p => {
            context.log("----> 2");
            page = p;
            return p.goto('https://www.example.com');
        }, failureCallback)
        .then(response => {
            context.log("----> 3");
            return page.screenshot({path: screenshotPath, fullPage: true});  
        }, failureCallback)
        .then(r => {
            browser.close();

            context.res = {
                body: "Done!"
            };

            context.done();            
        }, failureCallback);
};

以下是尝试执行脚本时的日志。

2017-12-18T04:32:05  Welcome, you are now connected to log-streaming service.
2017-12-18T04:33:05  No new trace in the past 1 min(s).
2017-12-18T04:33:11.400 Function started (Id=89b31468-8a5d-43cd-832f-b641216dffc0)
2017-12-18T04:33:20.578 JavaScript HTTP trigger function processed a request.
2017-12-18T04:33:20.578 --> Chrome Path D:\home\site\wwwroot\node_modules\puppeteer\.local-chromium\win64-508693\chrome-win32\chrome.exe
2017-12-18T04:33:20.578 --> Path = D:\local\Temp\screenshots\example.png
2017-12-18T04:33:20.965 --> Failure = 'Error: spawn UNKNOWN'
2017-12-18T04:33:20.965 ----> 2

错误“Failure = 'Error: spawn UNKNOWN'”不清楚。我使用 Kudu 和 PowerShell 确保我使用的路径是正确的。

我正在寻找一种在 Azure 云服务和/或 Azure Functions 上运行 Chrome 的方法(对于 Windows - 以便使用我现有的应用服务计划)。有人也尝试过在 Azure 中运行 Headless Chrome 吗?我愿意接受任何可以帮助我让这个脚本工作的想法?

【问题讨论】:

  • 如果您之前没有检查过,您可以检查这些建议,看看是否有帮助:social.msdn.microsoft.com/Forums/azure/en-US/…stackoverflow.com/questions/47265315/…
  • @Ashok - 我查看了这两个链接,但它们都没有提供如何在 Azure 云服务或 Azure Functions 中实现这一点的解决方案或想法。 :(
  • 云服务(带有角色)没有像应用服务那样的 GDI 限制。它应该可以正常工作,仔细检查您的路径,启用 RDP 并远程进入工作人员(如果这有助于调试)。
  • 或者只是尝试在容器中运行 Azure Functions。

标签: google-chrome azure azure-functions azure-cloud-services google-chrome-headless


【解决方案1】:

我建议使用https://www.browserless.io/,这样您就不必在应用服务中运行 chrome.exe。

将 puppeteer.launch 替换为 puppeteer.connect

const browser = await puppeteer.connect({
  browserWSEndpoint: 'wss://chrome.browserless.io/'
});

【讨论】:

  • BrowserLess 的另一个替代方案是headlesstesting.com - 提供 Chrome 和其他浏览器,兼容 Puppeteer 和 Playwright
【解决方案2】:

我不确定 Headless Chrome 的使用情况,但由于某些 GDI 限制,Azure Functions 运行的sandbox 在从 HTML 生成 PDF 时存在问题。

考虑在Azure Functions on Linux 中尝试您的任务。虽然这仍处于预览阶段,但它不使用沙箱,因此如果您可以使用无头 chrome 处理它,那么您可能会在 PDF 生成方面获得更多运气。

【讨论】:

  • Hello Conor - 我阅读了有关 Linux 上的 Azure Functions 的信息。我当前的 Web 应用程序在 Windows 上的云服务上运行。我觉得很遗憾必须创建一个新的服务工厂来生成 PDF 文件。那将是一个昂贵的文件生成器,每月 50 美元以上。
  • 马丁,这很公平。我相信正在做一些工作以允许 Linux 上的功能在消费计划上工作,这有望消除成本问题。不幸的是,我没有那个日期。
【解决方案3】:

Azure 允许 NodeJS:

您可以使用 Phantom 在 NodeJS 中执行此操作(而不是 chrome,因为您无法访问任何浏览器 - 也无法在 azure Web 应用程序上运行它们)查看示例 - 它托管在 google firebase 上,但您可以轻松将其应用到您的 NodeJS 项目中:

https://stackoverflow.com/a/51828577/6306638

如果您需要 Chrome,Azure VM 上的 IIS 服务器是您唯一的选择。

如果您需要任何帮助,请告诉我!

【讨论】:

  • @bhargav-rao 根据您的要求 :) 谢谢您的建议!我会确保在未来...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
相关资源
最近更新 更多