【问题标题】:Puppeteer Sharp strange behaviour傀儡师锋利的奇怪行为
【发布时间】:2019-09-18 05:02:26
【问题描述】:

我试图在另一个静态方法中调用Browser.NewPageAsync(),但是当我调用它时,调用它的方法就退出了。

    partial class Program
    {
        static Browser Browser;

        static async Task StartBrowser()
        {
            Browser = await Puppeteer.LaunchAsync
               (
                   new LaunchOptions
                   {
                       Headless = true,
                       ExecutablePath = "Chromium\\chrome.exe"
                   }
               );
            Console.WriteLine("Browser launched");
        }

        static void StartScraping(int threads)
        {
            for (int i = 0; i < threads; i++)
            {
                Task.Run(async () =>
                {
                    int ThreadNumber = i;
                    Console.WriteLine("Thread #" + ThreadNumber + " started");
                    Page p = await Browser.NewPageAsync(); //exits here
                    await p.GoToAsync("https://www.google.com");
                    Console.WriteLine("Content:\n" + await p.GetContentAsync());
                });
            }
        }

        static async Task MainAsync()
        {
            await StartBrowser();
            StartScraping(1);
        }

        static void Main(string[] args)
        {
            MainAsync().GetAwaiter().GetResult();
        }
    }

例如:如果我在MainAsync() 中调用Browser.NewPageAsync(),那么Browser.NewPageAsync() 将按预期调用。

【问题讨论】:

  • 在第 3 行中,您尝试声明一个与该类具有相同名称的变量,直到您尝试设置该变量,该变量才有效,然后编译器不知道您是否要使用浏览器类或浏览器变量。为避免此类问题,请遵守 C# 命名约定,并使用下划线和小写来命名您的浏览器变量,因为它是私有的静态变量。
  • 在Task.Run()中加入try()catch()并将Browser重命名为_Browser后没有发现异常

标签: c# async-await static-methods puppeteer-sharp


【解决方案1】:

我找到了解决方案: 如果页面将在与其浏览器实例相同的范围内创建,则页面将按预期创建,否则Task.Run() 将因NewPageAsync() 方法而卡住。

不良行为:

Task[] Tasks = new Task[1];
Browser browser = await Puppeteer.LaunchAsync
(
    new LaunchOptions
    {
        Headless = true,
        ExecutablePath = "Chromium\\chrome.exe"
    }
);
for (int i = 0; i < Tasks.Length; i++)
{
    int ThreadNumber = i;
    Tasks[i] = Task.Run(async () =>
    {
       Page page = await browser.NewPageAsync(); //stucks
    });
}

Task.WaitAll(Tasks);

如预期:

Task[] Tasks = new Task[1];
for (int i = 0; i < Tasks.Length; i++)
{
    int ThreadNumber = i;
    Tasks[i] = Task.Run(async () =>
    {
       Browser browser = await Puppeteer.LaunchAsync
       (
           new LaunchOptions
           {
                Headless = true,
               ExecutablePath = "Chromium\\chrome.exe"
           }
       );
       Page page = await browser.NewPageAsync(); //creates as expected
    });
}

Task.WaitAll(Tasks);

无论如何,这不是最好的解决方案,因为我必须为异步任务创建浏览器,而不是为所有异步任务使用一个浏览器。希望有人能解释一下。 感谢大家的帮助!

【讨论】:

    【解决方案2】:

    您正在开始任务,但没有等到完成。你需要等待他们:

        ...
        static void StartScraping(int threads)
        {
            Task.WaitAll(
                Enumerable.Range(0, threads)
                .Select(async ThreadNumber =>
                {
                    try
                    {
                        Console.WriteLine("Thread #" + ThreadNumber + " started");
                        Page p = await Browser.NewPageAsync(); //exits here
                        await p.GoToAsync("https://www.google.com");
                        Console.WriteLine("Content:\n" + await p.GetContentAsync());
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Thread #" + ThreadNumber + " failed. " + e);
                        throw;
                    }
                }).ToArray());
        }
    
        static async Task MainAsync()
        {
            await StartBrowser();
            StartScraping(1);
        }
    

    另外请检查这个 Puppeteer 问题:link。并确保 Chromium 版本与此处匹配:link

    【讨论】:

    • 在Task.Run()中加入try()catch()并将Browser重命名为_Browser后没有发现异常
    • @Steg_Brind,对,我已经用另一个建议更新了我的答案
    • Select 中出现此错误:无法从用法中推断方法“Enumerable.Select(IEnumerable, Func)”的类型参数.尝试明确指定类型参数。
    • @Steg_Brind,我忘记将 Func 设为 async。再修复一次
    • 好的,我编辑了你的答案 Renat,现在卡在 Page p = await Browser.NewPageAsync(); 猜这是 Puppeteer Sharp 的错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    • 2019-04-28
    • 1970-01-01
    • 2014-06-06
    相关资源
    最近更新 更多