playwright - 并行从多个页面获取内容

Posted

技术标签:

【中文标题】playwright - 并行从多个页面获取内容【英文标题】:playwright - get content from multiple pages in parallel 【发布时间】:2021-12-25 08:23:07 【问题描述】:

我正在尝试在 nodejs 应用程序中使用 playwright 从多个 URL 获取页面内容。我的代码如下所示:

const getContent = async (url: string): Promise<string> 
   const browser = await firefox.launch( headless: true );
   const page = await browser.newPage();

   try 
      await page.goto(url, 
         waitUntil: 'domcontentloaded',
      );

      return await page.content();
    finally 
      await page.close();
      await browser.close();
   


const items = [
   
      urls: ["https://www.google.com", "https://www.example.com"] 
      // other props
   ,
   
      urls: ["https://www.google.com", "https://www.example.com"] 
      // other props
   ,
   // more items...
]

await Promise.all(
   items.map(async (item) => 
      const contents = [];

      for (url in item.urls) 
         contents.push(await getContent(url))
      

      return contents;
   
)

我收到error (Page.content): Target closed. 之类的错误,但我注意到如果我只是在没有循环的情况下运行:

const content = getContent('https://www.example.com');

有效。

看起来循环的每次迭代都共享相同的浏览器和/或页面实例,因此它们正在关闭/导航彼此。

为了测试它,我使用 getContent 函数构建了一个 Web API,当我(几乎)同时发送 2 个请求时,其中一个失败,而不是同时发送一个请求,它始终有效。

有没有办法让剧作家并行工作?

【问题讨论】:

【参考方案1】:

我不知道这是否解决了它,但注意到有两个缺少等待。 firefox.launch(...) 和 browser.newPage() 都是异步的,需要在前面等待。

此外,您无需多次启动新浏览器。 PlayWright 具有isolated browser contexts 的功能,它的创建速度比启动浏览器要快得多。值得尝试在 getContent 函数之前启动浏览器,并使用

const context = await browser.newContext(); 
const page = await context.newPage();

【讨论】:

啊抱歉,我只是重写了我的实际代码的简化版本,我忘记了await。在实际代码中,我正在等待承诺。 我添加了一些关于使用新上下文而不是多次启动和关闭浏览器的信息。 还在此处添加了如何与一个浏览器但多个上下文并行下载的示例:github.com/microsoft/playwright/discussions/…

以上是关于playwright - 并行从多个页面获取内容的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 的 Playwright 中,如何从框架 (iframe) 中检索元素的句柄?

playwright自定义浏览器设备时区经纬度userAgent注入脚本

Hello Playwright:执行 JavaScript 代码

还是比Selenium好用?Python使用Splash访问谷歌获取相应内容

为啥在Python里推荐使用多进程而不是多线程

从 Rust 中的多个音频流中并行获取相同大小的块