0

我正在尝试在 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');

有用。

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

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

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

4

1 回答 1

0

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

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

const context = await browser.newContext(); 
const page = await context.newPage();
于 2021-11-13T10:45:20.777 回答