木偶从elementHandle获取元素导致协议错误

时间:2019-06-08 09:02:35

标签: 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();
})();

我要

  

错误:协议错误(Runtime.callFunctionOn):目标已关闭。什么时候   我正在尝试获取usernameElement

在此行:

  

let usernameUser =等待发布。$('。fwb');

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

1 个答案:

答案 0 :(得分:1)

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

要使其使用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;
}