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

行动起来,活在当下

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

目 录CONTENT

文章目录

.net core 3.1使用PuppeteerSharp截图(一窗体多窗口版)

管理员
2020-12-30 / 0 评论 / 0 点赞 / 5 阅读 / 27451 字
    public class PuppeteerSharpHelps
    {
        public PuppeteerSharpHelps()
        {
        }
        private static PuppeteerSharp.Browser _browser { get; set; }
        /// <summary>
        /// 截图完成回调
        /// </summary>
        public static event EventHandler ScreenshotComplete;
        /// <summary>
        /// 截图出错回调
        /// </summary>
        public static event EventHandler ScreenshotError;
        /// <summary>
        /// 初始化浏览
        /// </summary>
        /// <returns></returns>
        private async static Task<Browser> InItBrowser()
        {
            try
            {
                await slimLock.WaitAsync();
                var result = await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
                if (_browser == null)
                {
                    Debug.WriteLine("标识输出");
                    _browser = await Puppeteer.LaunchAsync(new LaunchOptions
                    {
                        Headless = true,
                        Args = new string[] {
                            "--disable-infobars",//隐藏 自动化标题
                            "--no-sandbox", // 沙盒模式
                        },
                    });
                    return _browser;
                }
                return _browser;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                slimLock.Release();
            }
        }
        /// <summary>
        /// 异步线程锁(让浏览器只初始化一次)
        /// </summary>
        private static SemaphoreSlim slimLock = new SemaphoreSlim(1, 1);
        /// <summary>
        /// 异步线程锁(锁定每次只处理10个任务)
        /// </summary>
        private static readonly SemaphoreSlim _mutex = new SemaphoreSlim(10);
        /// <summary>
        /// 异步截图
        /// </summary>
        /// <param name="loadUrl">加载的url</param>
        /// <param name="savePath">保存路径要带保存文件名称</param>
        /// <param name="width">设置浏览器的宽度</param>
        /// <param name="height">设置浏览器的高度</param>
        /// <param name="isTagName">判断当前传入的标签名称是否存在,存在则截图</param>
        /// <returns></returns>
        public static async Task ScreenshotAsync(string loadUrl, string savePath, string isTagName = null, string uniqueId = null, int width = 0, int height = 0)
        {
            try
            {
                await _mutex.WaitAsync();
                _browser ??= await InItBrowser();
                if (width == 0 || height == 0)
                {
                    await BrowserPages(_browser, loadUrl, savePath, isTagName);
                }
                else
                {
                    await BrowserPages(_browser, loadUrl, savePath, width, height, isTagName);
                }
            }
            catch (Exception ex)
            {
                if (_browser != null)
                {
                    await _browser?.CloseAsync();
                }
                _browser = null;
                GC.Collect();
                throw ex;
            }
            finally
            {
                _mutex.Release();
                GC.Collect();
            }
        }
        private static async Task BrowserPages(Browser browser, string loadUrl, string savePath, string isTagName, string uniqueId = null)
        {
            Page page = await browser.NewPageAsync();
            page.Load += async (sender, e) =>
            {
                try
                {
                    var _page = (Page)sender;
                    if (!string.IsNullOrEmpty(isTagName))
                    {
                        var tag = await page.QuerySelectorAsync(isTagName);
                        if (tag != null)
                        {
                            await page.ScreenshotAsync(savePath, new ScreenshotOptions() { Type = ScreenshotType.Png });
                            if (ScreenshotComplete != null)
                                ScreenshotComplete(savePath, new ScreenshotEventArgs() { IsScreenshot = true, SavePath = savePath, UniqueId = uniqueId });
                        }
                    }
                    await page.CloseAsync();
                }
                catch (Exception ex)
                {
                    //出错释放当前page资源
                    page.Dispose();
                    if (ScreenshotError != null)
                        ScreenshotError(savePath, new ScreenshotErrorEventArgs() { Error = ex, IsScreenshot = false, SavePath = savePath });
                }
            };
            page.Close += async (sender, e) =>
            {
                var pg = (Page)sender;
                var size = await pg.Browser.PagesAsync();
                if (size.Length <= 1)
                {
                    if (browser != null)
                    {
                        await browser.DisposeAsync();
                    }
                    browser = null;
                }
            };
            await page.SetViewportAsync(new ViewPortOptions
            {
                Width = 1000,
                Height = 1000
            });
            await page.GoToAsync(loadUrl);
        }
        private static async Task BrowserPages(Browser browser, string loadUrl, string savePath, int width, int height, string isTagName, string uniqueId = null)
        {
            Page page = await browser.NewPageAsync();
            //加载页面完成触发事件
            page.Load += async (sender, e) =>
            {
                try
                {
                    var load = (Page)sender;
                    if (!string.IsNullOrEmpty(isTagName))
                    {
                        var tag = await page.QuerySelectorAsync(isTagName);
                        if (tag != null)
                        {
                            await page.ScreenshotAsync(savePath, new ScreenshotOptions() { Type = ScreenshotType.Png });
                            if (ScreenshotComplete != null)
                                ScreenshotComplete(savePath, new ScreenshotEventArgs() { IsScreenshot = true, SavePath = savePath, UniqueId = uniqueId });
                        }
                    }
                    await page.CloseAsync();
                }
                catch (Exception ex)
                {
                    //出错释放当前page资源
                    page.Dispose();
                    if (ScreenshotError != null)
                        ScreenshotError(savePath, new ScreenshotErrorEventArgs() { Error = ex, IsScreenshot = false, SavePath = savePath });
                }
            };
            //关闭page窗口页触发事件
            page.Close += async (sender, e) =>
            {
                var pg = (Page)sender;
                var size = await pg.Browser.PagesAsync();
                if (size.Length <= 1)
                {
                    if (browser != null)
                    {
                        await browser.DisposeAsync();
                    }
                    browser = null;
                }
            };
            await page.SetViewportAsync(new ViewPortOptions
            {
                Width = width,
                Height = height
            });
            await page.GoToAsync(loadUrl);
        }
    }
    public class ScreenshotEventArgs : EventArgs
    {
        /// <summary>
        /// 截图成功为true
        /// </summary>
        public bool IsScreenshot { get; set; }
        /// <summary>
        /// 截图保存的路径
        /// </summary>
        public string SavePath { get; set; }
    }
    public class ScreenshotErrorEventArgs : EventArgs
    {
        /// <summary>
        /// 截图成功为true
        /// </summary>
        public bool IsScreenshot { get; set; }
        /// <summary>
        /// 截图保存的路径
        /// </summary>
        public string SavePath { get; set; }
        /// <summary>
        /// 出错内容
        /// </summary>
        public object Error { get; set; }
    }

测试:

for (int i = 1; i <= 50; i++)
                {
                    if ((i % 2) == 0)
                    {
                        PuppeteerSharpHelps.ScreenshotAsync("https://www.baidu.com", $"F://test{i}.png", i);
                    }
                    else
                    {
                        PuppeteerSharpHelps.ScreenshotAsync("https://www.csdn.net/", $"F://test{i}.png", i);
                    }
                }


0

评论区