如何通过从多个 div 中选择它来获取 Facebook 群组 post div 中的 post link?

How can I fetch the post link in a Facebook Group post div by selecting it out of multiple divs?

所以我正在开发这个人偶应用程序,它需要我在 Facebook 群组 post 中获取 post link,尤其是 link post 即作者姓名下方 post 的 time and date。我只想为第一个 post 获取 post link。

因此,要做到这一点,我必须从 selecting post 的最外层 div 开始,即 parent。并且 apparently 每个 post 在提要中包含相同的 class,如这张照片所示:

上图显示了 Facebook 提要的典型 html 结构。第一个childdiv是New Activity标题div。而其他child人是postdiv人。我只对第一个 post div 感兴趣,也就是上图中的 Post 1

我感兴趣的锚点link嵌套得很深。大概有 10-15 层深。并且可能有一百万个锚link。因此,为了缩小范围,我可以只在 post.

的 header 中获取 links

下图显示了 parent div 和 header div 的结构:

这张图片显示了我正在尝试获取的link。

我知道上面的图片太夸张了,但这是我可以解释我一直在尝试做的事情的最简单方法。问题是我无法使用实际的 selectors。我是 Puppeteer 的新手,它的语法对我来说有点复杂。因此,用最简单的话来说,我想从您那里得到的是 select 多个相同 class div 中的第一个 Post 1 div。这是最重要的部分。然后选择带有 classes 的内部 divs 到实际锚点 link.

除了我尝试过的所有代码之外,这是其中之一:

const postDivs = await page.$$( 'div[role="feed"] .du4w35lb' );

const hrefs = await page.$$eval( `${postDivs[ 0 ]} .pybr56ya .buofh1pr a`, links => links.map( a => a.href ) );

console.log( 'anchor link: ', hrefs );

上面的代码 returns 一个错误说:

Error: Evaluation failed: DOMException: Failed to execute 'querySelectorAll' on
'Document': 'JSHandle@node .pybr56ya .buofh1pr a' is not a valid selector.

希望得到您的肯定答复。

更新*** 这是我用来 抓取 锚 links:

的代码
( async () => {
    try {

        const browser = await puppeteer.launch( {
            headless: false,
            args: [ '--no-sandbox', '--allow-third-party-modules', '--start-maximized' ],
            slowMo: 10
        } );

        const context = await browser.createIncognitoBrowserContext();
        const page = await context.newPage();

        // go to webpage
        await page.goto( 'https://www.facebook.com', { waitUntil: 'networkidle2' } );

        // fill login details and submit
        await page.waitForSelector( "#email" );
        await page.focus( "#email" );
        await page.type( "#email", "myEmailId", { delay: 50 } );
        await page.waitForSelector( "#pass" );
        await page.focus( "#pass" );
        await page.type( "#pass", "myPassword", { delay: 50 } );
        await page.click( `[type="submit"]` );

        await page.waitForNavigation();
        await page.goto( "https://www.facebook.com/groups/groupName", { waitUntil: 'networkidle2' } );


        await page.waitForTimeout( 5000 );

        // code to fetch the links
        const links = await page.evaluate( function () {
            return [ ...document.querySelectorAll( 'div[role=feed] .du4w35lb .buofh1pr .tojvnm2t .oajrlxb2[role=link]' ) ].map( ( link ) => link.href );
        } );

        console.log( 'links: ', links );

        await page.waitForTimeout( 5000 );


        // close browser
        await browser.close()


    } catch ( err ) {
        console.log( err );
    }
} )();

你必须找到一个足够独特的选择器,只挑选出你需要的东西。要做到这一点,您可以尝试将 类 从几个级别串在一起,导致 link 与日期(但不会导致其他 links,如配置文件 links,因此“足够独特”)。

我在一个随机的 FB 讨论组中做了一个快速实验,其中的选择器目前与您的选择器非常相似,并想出了这个选择器来找到 link 到帖子:

const links = await page.evaluate(function(){
  return [...document.querySelectorAll('div[role=feed] .du4w35lb .buofh1pr .tojvnm2t .oajrlxb2[role=link]')].map((link) => link.href);
});

它应该产生这样的数组:

[
  "https://www.facebook.com/groups/somegroup/permalink/1244304367068568/?__cft__[0]=AZXxG8lKJxPS9bC&__tn__=%2CO%2CP-R",
  "https://www.facebook.com/groups/somegroup/permalink/1243163367516017/?__cft__[0]=AZXcER8tI9lU1EL&__tn__=%2CO%2CP-R",
  "https://www.facebook.com/groups/somegroup/permalink/1245602367605409/?__cft__[0]=AZW9cets_p3QIyB&__tn__=%2CO%2CP-R",
  "https://www.facebook.com/groups/somegroup/permalink/1248223367343307/?__cft__[0]=AZV-htDstk_4Gsn&__tn__=%2CO%2CP-R",
  "https://www.facebook.com/groups/somegroup/permalink/1247711367061195/?__cft__[0]=AZW2depBCCmRtXC&__tn__=%2CO%2CP-R",
  "https://www.facebook.com/groups/somegroup#",
  "https://www.facebook.com/groups/somegroup#"
]

请注意最后两个元素:显然,您需要将光标悬停在日期 link 上,FB 才能动态计算 href,因此请记住这一点。