【问题标题】:Get the root document object outside page.evaluate in Puppeteer.js在 Puppeteer.js 中获取 page.evaluate 之外的根文档对象
【发布时间】:2023-03-17 09:11:01
【问题描述】:

我正在使用 Puppeteer.js 来抓取一些页面。目前,我使用jsdom 对DOM 执行大量查询。今天这是不可能的,你可以在下面的代码中看到,并在评论中解释:

const puppeteer = require('puppeteer');
(async () => {
    const browser = await puppeteer.launch({ headless: false });
    const page = await browser.newPage();
    // Instructs the blank page to navigate a URL
    await page.goto('https://www.google.com/');
    const result = await page.evaluate(() => {});
    await browser.close();
})();

这里我有可用的“文档”对象。我想在这个范围之外评估它, 因为我在这里对 DOM 进行了很多调查,我不想在这里弄乱 puppeteer 代码。 我不能在这里调用任何外部函数。

const result = await page.evaluate(() => {});

今天,我需要导出所有的HTML页面,而不是这个, 并将其发送到其他文件中的 jsdom 等外部包:

const jsdom = require('jsdom');
const pageContent = await page.content();
const dom = new jsdom.JSDOM(pageContent);
const divs = dom.window.document.querySelectorAll('div');
// Rest of the long investigation here.

我需要什么?

const dom = await page.contentDOM();
const divs = dom.window.document.querySelectorAll('div');
    // Rest of the long investigation here.

所以基本上,我的问题是,Puppeeter.js 中内置了一些函数,可以将文档根对象暴露在 page.evaluate 之外,这将允许我将文档移动到其他函数以调查那里的 DOM,或者我现在还需要使用外部包,比如jsdom

试图在这里寻找答案:
Getting DOM node text with Puppeteer and headless Chrome
Using puppeteer how do you get all child nodes of a node?
Getting all styles with devtool-protocol in puppeteer
Get DocType of an HTML as string with Javascript
Handling events from puppeteer's page context outside evaluate method
Headless Chrome ( Puppeteer ) - how to get access to document node element?

我最近在 Puppeeter.js GitHub 页面上打开了问题,但没有答案:
https://github.com/puppeteer/puppeteer/issues/6667

提前致谢。

【问题讨论】:

    标签: javascript node.js dom puppeteer


    【解决方案1】:

    我不是抓取或类似问题的专家,所以我可能是错的,但我认为 puppeteer 可以做 jsdom 可以做的任何事情,还可以执行 javascript。我发现这四个功能真的很有帮助

    page.$$:使用 querySelectorAll 获取元素并返回一个 ElementHandle 数组,以便在 Node 中使用

    page.$: 使用 querySelector 获取元素并返回一个 ElementHandle 以使其在 Node 中可用

    page.$$eval:对querySelectorAll执行回调并返回回调结果

    page.$eval:在querySelector上执行回调并返回回调结果

    如果你想要页面中的 html,我发现了这个 answer

    const renderedContent = await page.evaluate(() => new XMLSerializer().serializeToString(document));
    

    【讨论】:

    • 遗憾的是,这不是我要找的。我想获得具有'getElementById`和querySelectorAll的所有功能的document。这只会给我字符串 HTML。顺便提一下,通过await page.content(),就一样了。
    • 您是否考虑过使用 page.exposeFunction 将您的函数加载到页面中,以便在调用 page.evaluate 时更易于阅读?这是 page.exposeFunction pptr.dev/… 的文档
    • 即使这可行,它如何满足我的需求?我需要一个像我从 jsDOM 包中获得的对象 - 一个包含所有 'querySelectAll' 和 'getElemenetById' 类函数的根文档,在 page.evaluate 函数之外。
    • 我认为您使用 jsdom 的原因是因为您有很多不想嵌套在 page.evaluate 中的 dom 查询。您是否考虑过忘记 puppeteer 并使用 JSDOM.fromURL
    • 我希望将所有内容合并到一个包中。我需要在特定部分执行爬取,并在其他部分执行长时间的 DOM 调查,但在同一个 URL 中。
    猜你喜欢
    • 2017-09-28
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2011-11-26
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 2018-05-21
    相关资源
    最近更新 更多