如何通过从多个 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,因此请记住这一点。
所以我正在开发这个人偶应用程序,它需要我在 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,因此请记住这一点。