侧边栏壁纸
博主头像
分享你我博主等级

行动起来,活在当下

  • 累计撰写 107 篇文章
  • 累计创建 13 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

.net core 使用PuppeteerSharp截图稳定版

管理员
2021-04-16 / 0 评论 / 0 点赞 / 5 阅读 / 45509 字


目前在64GB RAM 的centos 服务器上同时开100个也没有压力


 public sealed class PuppeteerSharpUtil
    {
        private static Browser _browser { get; set; }
        /// <summary>
        /// 异步线程锁(让浏览器只初始化一次)
        /// </summary>
        private static SemaphoreSlim slimLock = new SemaphoreSlim(1, 1);
        /// <summary>
        /// 初始化浏览
        /// </summary>
        /// <returns></returns>
        private async static Task InItBrowser()
        {
            try
            {
                await slimLock.WaitAsync();
                if (_browser == null)
                {
                    //不存在则下载浏览器
                    var result = await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
                    _browser = await Puppeteer.LaunchAsync(new LaunchOptions
                    {
                        Headless = true,
                        Args = new string[] {
                            "--disable-infobars",//隐藏 自动化标题
                            "--no-sandbox", // 沙盒模式
                        },
                    });
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                slimLock.Release();
            }
        }
        /// <summary>
        /// 异步线程锁(锁定每次只处理10个任务)
        /// </summary>
        private static readonly SemaphoreSlim _mutex = new SemaphoreSlim(ConfigExtensions.Configuration["pageCnt"].ToInt(10));
        /// <summary>
        /// 异步截图
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="url">加载的url地址</param>
        /// <param name="savePath">保存路径</param>
        /// <param name="isTagName">标识(用于判断网页是否加载某个模块)</param>
        /// <param name="action">截图完成后要执行的方法</param>
        /// <param name="par1">参数1</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        public static async Task ScreenshotAsync<T1>(string url, string savePath, string isTagName, Action<T1> action, T1 par1, int width = 1000, int height = 1000)
        {
            try
            {
                await _mutex.WaitAsync();
                if (_browser == null) await InItBrowser();
                using Page page = await _browser.NewPageAsync();
                try
                {
                    await page.SetViewportAsync(new ViewPortOptions
                    {
                        Width = width,
                        Height = height
                    });
                    WaitUntilNavigation[] wn = new WaitUntilNavigation[50];
                    wn[0] = WaitUntilNavigation.DOMContentLoaded;
                    wn[1] = WaitUntilNavigation.Load;
                    await page.SetViewportAsync(new ViewPortOptions
                    {
                        Width = width,
                        Height = height
                    });
                    await page.GoToAsync(url, new NavigationOptions() { WaitUntil = wn });
                    var selector = await page.WaitForSelectorAsync(isTagName, new WaitForSelectorOptions() { Timeout = ConfigExtensions.Configuration["ScreensTimeout"].ToInt(30000) });
                    if (selector != null)
                    {
                        await page.ScreenshotAsync(savePath,
                            new ScreenshotOptions
                            {
                                Type = ScreenshotType.Png,
                            });
                        action(par1);
                    }
                    else
                    {
                        NLogHelp.InfoLog(url + "-----Selector查询不到头部" + selector.ToString() + "-------" + isTagName);
                    }
                }
                catch (Exception ex)
                {
                    page.Dispose();
                    NLogHelp.ErrorLog(url + "-----截图出错", ex);
                }
            }
            catch (Exception ex)
            {
                NLogHelp.ErrorLog("截图----出错:", ex);
                GC.Collect();
                throw ex;
            }
            finally
            {
                _mutex.Release();
                GC.Collect();
            }
        }
         /// <summary>
        /// 异步截图
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="url">加载的url地址</param>
        /// <param name="savePath">保存路径</param>
        /// <param name="isTagName">标识(用于判断网页是否加载某个模块)</param>
        /// <param name="action">截图完成后要执行的方法</param>
        /// <param name="par1">参数1</param>
        /// <param name="par2">参数2</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        public static async Task ScreenshotAsync<T1, T2>(string url, string savePath, string isTagName, Action<T1, T2> action, T1 par1, T2 par2, int width = 1000, int height = 1000)
        {
            try
            {
                await _mutex.WaitAsync();
                if (_browser == null) await InItBrowser();
                using Page page = await _browser.NewPageAsync();
                try
                {
                    await page.SetViewportAsync(new ViewPortOptions
                    {
                        Width = width,
                        Height = height
                    });
                    WaitUntilNavigation[] wn = new WaitUntilNavigation[50];
                    wn[0] = WaitUntilNavigation.DOMContentLoaded;
                    wn[1] = WaitUntilNavigation.Load;
                    await page.SetViewportAsync(new ViewPortOptions
                    {
                        Width = width,
                        Height = height
                    });
                    await page.GoToAsync(url, new NavigationOptions() { WaitUntil = wn });
                    var selector = await page.WaitForSelectorAsync(isTagName, new WaitForSelectorOptions() { Timeout = ConfigExtensions.Configuration["ScreensTimeout"].ToInt(30000) });
                    if (selector != null)
                    {
                        await page.ScreenshotAsync(savePath,
                            new ScreenshotOptions
                            {
                                Type = ScreenshotType.Png,
                            });
                        action?.Invoke(par1, par2);
                    }
                    else
                    {
                        NLogHelp.InfoLog(url + "-----Selector查询不到头部" + selector.ToString() + "-------" + isTagName);
                    }
                }
                catch (Exception ex)
                {
                    page.Dispose();
                    NLogHelp.ErrorLog(url + "-----截图出错", ex);
                }
            }
            catch (Exception ex)
            {
                NLogHelp.ErrorLog("截图----出错:", ex);
                GC.Collect();
                throw ex;
            }
            finally
            {
                _mutex.Release();
                GC.Collect();
            }
        }
                /// <summary>
        /// 异步截图
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="url">加载的url地址</param>
        /// <param name="savePath">保存路径</param>
        /// <param name="isTagName">标识(用于判断网页是否加载某个模块)</param>
        /// <param name="action">截图完成后要执行的方法</param>
        /// <param name="par1">参数1</param>
        /// <param name="par2">参数2</param>
        /// <param name="par3">参数3</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        public static async Task ScreenshotAsync<T1, T2, T3>(string url, string savePath, string isTagName, Action<T1, T2, T3> action, T1 par1, T2 par2, T3 par3, int width = 1080, int height = 1920)
        {
            await _mutex.WaitAsync();
            if (_browser == null) await InItBrowser();
            try
            {
                await Task.Run(async () =>
                {
                    using Page page = await _browser.NewPageAsync();
                    try
                    {
                        await page.SetViewportAsync(new ViewPortOptions
                        {
                            Width = width,
                            Height = height
                        });
                        WaitUntilNavigation[] wn = new WaitUntilNavigation[50];
                        wn[0] = WaitUntilNavigation.DOMContentLoaded;
                        wn[1] = WaitUntilNavigation.Load;
                        await page.SetViewportAsync(new ViewPortOptions
                        {
                            Width = width,
                            Height = height
                        });
                        await page.GoToAsync(url, new NavigationOptions() { WaitUntil = wn });
                        var selector = await page.WaitForSelectorAsync(isTagName, new WaitForSelectorOptions() { Timeout = ConfigExtensions.Configuration["ScreensTimeout"].ToInt(30000) });
                        if (selector != null)
                        {
                            await page.ScreenshotAsync(savePath,
                                new ScreenshotOptions
                                {
                                    Type = ScreenshotType.Png,
                                });
                            action?.Invoke(par1, par2, par3);
                        }
                        else
                        {
                            NLogHelp.InfoLog(url + "-----Selector查询不到头部" + selector.ToString() + "-------" + isTagName);
                        }
                    }
                    catch (Exception ex)
                    {
                        page.Dispose();
                        NLogHelp.ErrorLog(url + "-----截图出错", ex);
                    }
                });
            }
            catch (Exception ex)
            {
                GC.Collect();
                NLogHelp.ErrorLog("截图----出错:", ex);
                throw ex;
            }
            finally
            {
                _mutex.Release();
                GC.Collect();
            }
        }
        /// <summary>
        /// 异步截图
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <param name="url">加载的url地址</param>
        /// <param name="savePath">保存路径</param>
        /// <param name="isTagName">标识(用于判断网页是否加载某个模块)</param>
        /// <param name="action">截图完成后要执行的方法</param>
        /// <param name="par1">参数1</param>
         /// <param name="par2">参数2</param>
          /// <param name="par3">参数3</param>
           /// <param name="par4">参数4</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        public static async Task ScreenshotAsync<T1, T2, T3, T4>(string url, string savePath, string isTagName, Action<T1, T2, T3, T4> action, T1 par1, T2 par2, T3 par3, T4 par4, int width = 1000, int height = 1000)
        {
            NLogHelp.InfoLog(url + "截图进来时间----:" + par4 + "  -----------" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            await _mutex.WaitAsync();
            if (_browser == null) await InItBrowser();
            try
            {
                await Task.Run(async () =>
                  {
                      using Page page = await _browser.NewPageAsync();
                      try
                      {
                          await page.SetViewportAsync(new ViewPortOptions
                          {
                              Width = width,
                              Height = height
                          });
                          WaitUntilNavigation[] wn = new WaitUntilNavigation[50];
                          wn[0] = WaitUntilNavigation.DOMContentLoaded;
                          wn[1] = WaitUntilNavigation.Load;
                          await page.SetViewportAsync(new ViewPortOptions
                          {
                              Width = width,
                              Height = height
                          });
                          await page.GoToAsync(url, new NavigationOptions() { WaitUntil = wn });
                          var selector = await page.WaitForSelectorAsync(isTagName, new WaitForSelectorOptions() { Timeout = ConfigExtensions.Configuration["ScreensTimeout"].ToInt(30000) });
                          if (selector != null)
                          {
                              await page.ScreenshotAsync(savePath,
                                  new ScreenshotOptions
                                  {
                                      Type = ScreenshotType.Png,
                                  });
                              action?.Invoke(par1, par2, par3, par4);
                          }
                          else
                          {
                              NLogHelp.InfoLog(url + "-----Selector查询不到头部" + selector.ToString() + "-------" + isTagName);
                          }
                      }
                      catch (Exception ex)
                      {
                          page.Dispose();
                          NLogHelp.ErrorLog(url + "-----截图出错", ex);
                      }
                  });
            }
            catch (Exception ex)
            {
                GC.Collect();
                NLogHelp.ErrorLog("截图----出错:", ex);
                throw ex;
            }
            finally
            {
                _mutex.Release();
                GC.Collect();
            }
            
        }
    }


0

评论区