如何将 ElementHandle 移动到另一个页面

How to move ElementHandle to another Page

我正在尝试迭代一个 ElementHandles 数组并将它们附加到第二个页面中,如下所示:

const htmlContent: string = `
    <html><head></head><body>
        <div class="section">Section 1</div>
        <div class="section">Section 2</div>
        <div class="main-container"></div>
    </body></html>`

let browser: Browser = await Puppeteer.launch();
const firstPage: Page = await browser.newPage();
const secondPage: Page = await browser.newPage();
await firstPage.goto('data:text/html;charset=UTF-8,' + htmlContent);
await secondPage.goto('data:text/html;charset=UTF-8,' + htmlContent);
let sections: ElementHandle[] = await firstPage.$$('.section');

for (const section of sections) {
    secondPage.$eval('.main-container', (el: any, section: ElementHandle) => {
        el.append(section);
    }, section);
}

browser.close()

我将此代码基于 class ElementHandle 的 Puppeteer 文档:

ElementHandle instances can be used as arguments in page.$eval() and page.evaluate() methods.

但是,这不起作用。它生成一个包含以下消息的堆栈跟踪:

Error: JSHandles can be evaluated only in the context they were created!

我尝试将部分定义为 anyJSHandle,结果相同。 我一直在 api 文档中搜索任何关于我做错了什么的提示,但没有结果。

如有任何帮助,我们将不胜感激!

错误消息指的“上下文”是页面——您正试图将元素从一个页面复制到另一个页面,它根本不允许您这样做,不幸的是,没有办法序列化它们,所以你可以通过它们。也就是说,只要丢失任何带外数据(例如 JavaScript 中设置的事件侦听器或其他属性)是可以接受的,您就可以复制 outerHTML

const htmlContent: string = `
<html><head></head><body>
<div class="section">Section 1</div>
<div class="section">Section 2</div>
<div class="main-container"></div>
</body></html>`;

let browser: Browser = await Puppeteer.launch();
const firstPage: Page = await browser.newPage();
const secondPage: Page = await browser.newPage();
await firstPage.goto("data:text/html;charset=UTF-8," + htmlContent);
await secondPage.goto("data:text/html;charset=UTF-8," + htmlContent);
let sectionsAsHtml: string[] = await firstPage.$$eval(
  ".section",
  (elements: Element[]) => Array.from(elements).map(e => e.outerHTML)
);

for (const section of sectionsAsHtml) {
  await secondPage.$eval(".main-container", e => (e.innerHTML += section));
}

browser.close();