node.js - Puppeteer 从 elementHandle 获取元素导致协议(protocol)错误

标签 node.js web-scraping puppeteer

我正在尝试抓取某个 Facebook 页面,查找由某个用户撰写并以某个单词开头的帖子。

const puppeteer = require('puppeteer');

async function findPosts(page) {
    const USERNAME = 'test123';
    const posts = await page.$$('.userContentWrapper');
    return posts.filter(async post => {
        try {
            let usernameElement = await post.$('.fwb');
            let username = await page.evaluate(element => element.textContent, usernameElement);
            if (username === USERNAME) {
                let postElement = await post.$('[data-testid="post_message"] p');
                let postContent = page.evaluate(element => element.textContent, postElement);
                return /\[test \d+\]/.test(postContent);
            }
            return false;
        } catch(e) {
            console.log(e);
            return false;
        }
    });
}


(async () => {
    const browser = await puppeteer.launch({
        headless: false
    });
    const page = await browser.newPage();
    await page.goto('https://www.facebook.com/groups/groupid/');
    const pageTitle = await page.title();
    console.log(pageTitle);
    const posts = await findPosts(page);
    console.log(posts);
    await browser.close();
})();

我懂了

Error: Protocol error (Runtime.callFunctionOn): Target closed. when I'm trying to get the usernameElement

在这一行:

let usernameElement = await post.$('.fwb');

不确定这里出了什么问题,有什么建议吗?

最佳答案

问题是filter函数不适用于 Promise。因此,return posts.filter(...) 将立即返回,然后浏览器将关闭。因此,当您尝试在页面上运行 $ 函数时,该页面不再存在,并且您会收到 Target close 错误。

要使其使用 async/await 语法,您可以使用简单的循环:

async function findPosts(page) {
    const USERNAME = 'test123';
    const posts = await page.$$('.userContentWrapper');
    const postsToReturn = [];
    for (let post of posts) {
        /* ... if else logic */
        postsToReturn.push(post); // instead of return true
    }
    return postsToReturn;
}

关于node.js - Puppeteer 从 elementHandle 获取元素导致协议(protocol)错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56504948/

相关文章:

node.js - 如何禁用nodejs ChildProcess.spawn stdout 缓冲区?

c# - 无法创建 ssl/tls 安全通道。 HTML 敏捷性

json - 将多个 cookie 传递给 puppeteer

javascript - PUPPETEER - 循环内的随机设置超时不起作用

node.js - oclif 无法识别创建的命令

javascript - "While"阻塞异步操作

python - 尝试使用 requests-html 抓取 JS Web 时出现问题(Python 3.6)

xpath - Google 表格 - 在特定页面上导入 XML 时遇到问题

javascript - Puppeteer page.content() - 将已解决的 promise 写入列表

javascript - Sequelize : TypeError: Cannot read property 'length' of undefined when try to create data on DB