kpeng163 2024-09-07 15:38 采纳率: 90.9%
浏览 11
已结题

netcore使用PuppeteerSharp截图

.net6.0 ,使用PuppeteerSharp来做页面截图,PuppeteerSharp版本18.1.0.0
本地运行一切正常,后来发布到iis后,竟然被告知有问题。发布到iis后,生成的图片时好时坏的,大概一半一半吧,不正常时为空白,排查半天也没结果,用了最简单的逻辑和代码,问题依然存在。以下代码执行无报错,图片能生成,就是有时生成的图片不对

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>
            11111111
    <script>
                   window.isDone = 1;
    </script>
</body>

</html>

await using var browser = await Puppeteer.LaunchAsync(
   new LaunchOptions { Headless = true });
await using var page = await browser.NewPageAsync();
await page.GoToAsync(url);
await page.WaitForFunctionAsync("() => window.isDone === 1");
await page.ScreenshotAsync("212121.PNG");
 await browser.CloseAsync();

附上截图效果。

img

img

  • 写回答

24条回答 默认 最新

  • guicai_guojia 2024-09-07 22:55
    关注

    chatgpt回答如下

    
    bash
    
    你在使用 `PuppeteerSharp` 做页面截图时,遇到了部署在 IIS 上生成图片不稳定的问题,有时图片为空白。这种情况通常和几个因素有关,比如异步加载、页面渲染时间、IIS 环境差异等。
    
    以下几点可以帮助你排查并解决问题:
    
    ### 1. **延迟页面截图以等待页面完全加载**
       页面可能未完全渲染或 JavaScript 未完全执行就进行了截图。你可以在确保页面加载完成后再截图,使用 `WaitForSelector` 或自定义等待条件。
    
       试试修改你的代码,确保页面渲染完成后再截图,例如:
    
       csharpa
       using PuppeteerSharp;
    
       public async Task CaptureScreenshotAsync()
       {
           var browserFetcher = new BrowserFetcher();
           await browserFetcher.DownloadAsync(BrowserFetcher.DefaultChromiumRevision);
    
           var browser = await Puppeteer.LaunchAsync(new LaunchOptions
           {
               Headless = true,  // 是否以无头模式启动
               Args = new[] { "--no-sandbox", "--disable-setuid-sandbox" } // 添加相关的安全参数,避免权限问题
           });
    
           var page = await browser.NewPageAsync();
    
           // 打开页面
           await page.GoToAsync("http://localhost/yourpage", WaitUntilNavigation.Networkidle0);
    
           // 检查是否页面渲染完成,例如等待某个标志
           await page.WaitForFunctionAsync("() => window.isDone === 1");
    
           // 截图
           await page.ScreenshotAsync("screenshot.png", new ScreenshotOptions
           {
               FullPage = true
           });
    
           await browser.CloseAsync();
       }
       
    
       - `WaitUntilNavigation.Networkidle0`:等待页面加载完成,网络连接空闲。
       - `WaitForFunctionAsync("() => window.isDone === 1")`:等待页面脚本设置的 `window.isDone` 标志为 1,以确保页面完成渲染。
    
    ### 2. **检查 IIS 的权限问题**
       在 IIS 上运行 `PuppeteerSharp` 需要足够的权限,特别是如果你使用了 `Headless` 模式并且在后台处理 Chromium 进程时。
    
       - 确保 IIS 应用程序池的账户有执行权限,可以访问 Chromium 的所有文件夹,并能够写入截图输出目录。
       - 检查 IIS 用户是否有足够的系统资源(例如 CPU、内存)运行 Chromium。`IIS` 中应用程序池的 `AppPool` 用户权限可能有限。
       - 检查 IIS 中应用程序池的 **加载用户配置文件** 选项是否启用:
         1. 打开 IIS 管理器。
         2. 选择对应的应用程序池。
         3. 点击右侧的“高级设置”。
         4. 确保“加载用户配置文件”选项设置为 `True`。
    
    ### 3. **Chromium 的启动参数**
       如果服务器环境和本地环境不完全一致,可能需要为 IIS 环境增加一些启动参数,以确保 `Puppeteer` 正常运行。
    
       一些常用的参数:
       csharp
       var launchOptions = new LaunchOptions
       {
           Headless = true,
           Args = new[]
           {
               "--no-sandbox",
               "--disable-setuid-sandbox",
               "--disable-gpu", 
               "--disable-dev-shm-usage", // 避免共享内存问题
               "--disable-extensions",
               "--disable-software-rasterizer", // 如果服务器禁用了 GPU
               "--remote-debugging-port=9222" // 如果你需要远程调试
           }
       };
       
    
    ### 4. **日志记录**
       为了更好地诊断问题,可以启用 Chromium 的调试日志,查看更多输出信息:
       csharp
       var launchOptions = new LaunchOptions
       {
           Headless = true,
           Args = new[] { "--no-sandbox", "--disable-setuid-sandbox" },
           DumpIO = true, // 输出调试信息到控制台
           LogProcess = true // 启用日志
       };
       
    
       如果截图为空白,可能是因为页面加载或渲染遇到错误,通过日志可以发现更多信息。
    
    ### 5. **服务器资源问题**
       确保服务器资源(如 CPU、内存)足够,Chromium 启动时可能会消耗大量内存。如果服务器资源不足,渲染可能失败。你可以通过监控服务器的资源使用情况来排查这个问题。
    
    ### 6. **超时问题**
       页面加载可能需要较长时间,尝试增加 `GoToAsync` 的超时参数,以防止页面未完全加载就截图。
    
       csharp
       await page.GoToAsync("http://localhost/yourpage", new NavigationOptions
       {
           Timeout = 30000, // 30秒超时
           WaitUntil = new[] { WaitUntilNavigation.Networkidle0 }
       });
       
    
    ### 7. **缓存问题**
       有时 IIS 可能在页面之间缓存资源,导致截图效果不一致。你可以尝试在截图前清除页面缓存:
       csharp
       await page.SetCacheEnabledAsync(false);
       
    
    通过以上方法,你可以更好地控制页面的加载和渲染过程,确保在 IIS 环境下的 `PuppeteerSharp` 截图功能更加稳定。
    
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(23条)

报告相同问题?

问题事件

  • 系统已结题 9月21日
  • 已采纳回答 9月13日
  • 修改了问题 9月7日
  • 创建了问题 9月7日

悬赏问题

  • ¥15 如何构建全国统一的物流管理平台?
  • ¥100 ijkplayer使用AndroidStudio/CMake编译,如何支持 rtsp 直播流?
  • ¥20 和学习数据的传参方式,选择正确的传参方式有关
  • ¥15 这是网络安全里面的poem code
  • ¥15 用js遍历数据并对非空元素添加css样式
  • ¥15 使用autodl云训练,希望有直接运行的代码(关键词-数据集)
  • ¥50 python写segy数据出错
  • ¥20 关于线性结构的问题:希望能从头到尾完整地帮我改一下,困扰我很久了
  • ¥30 3D多模态医疗数据集-视觉问答
  • ¥20 设计一个二极管稳压值检测电路