我在 youtube 上尝试使用 puppeteer,我试图从 youtube 主页的缩略图中抓取 URL src 和标题文本,抓取程序运行良好。问题是当它抓取缩略图的标题和 src 时,程序在记录 URL src 时开始跳行,但它对文本数据工作正常。当我试图理解行跳转递归性时,每次程序抓取信息后,都会一次又一次地跳转 7 行,然后一次又一次地跳转 14 行。我无法弄清楚为什么在抓取 URL src 而不是文本标题时会发生行跳转。和我的无限滚动处理方式有关系吗?
async function scrape(url) {
const browser = await puppeteer.launch({
headless: false
});
const page = await browser.newPage();
await page.setViewport({
width: 1200,
height: 800
});
const navigationPromise = page.waitForNavigation();
await page.goto(url, {
timeout: 0
});
await page.evaluate(_ => {
window.scrollBy(0, window.innerHeight);
});
await page.waitFor(5000);
await page.waitForSelector('#img')
await navigationPromise;
const loadThumbnailText = [];
const loadThumbnailSrc = [];
var ytTextData;
for (let i = 0; i < 50; i++) {
const textSelector = 'h3 > a > #video-title'
const srcSelector = 'ytd-thumbnail > a > yt-img-shadow > #img'
await page.waitForSelector(textSelector)
await page.waitForSelector(srcSelector)
const ytTextData = await page.$$eval(textSelector, elems => elems.map(el => el.textContent).join('\n'))
const ytSrcData = await page.$$eval(srcSelector, elems => elems.map(el => el.src).join('\n'))
if (ytTextData && ytSrcData) {
console.log({
ytTextData,
ytSrcData
})
loadThumbnailText.push(ytTextData);
loadThumbnailSrc.push(ytSrcData);
console.log(ytTextData, ytSrcData)
}
}
browser.close();
}
答案 0 :(得分:1)
问题似乎出在您拥有的选择器上。我在 youtube.com 上的控制台中运行了以下内容:
document.querySelectorAll('h3 > a > #video-title').length
document.querySelectorAll('ytd-thumbnail > a > yt-img-shadow > #img').length
第一个给了我 29,第二个给了我 42。看起来主页上有隐藏的视频,只有点击向下箭头才会显示。您的文本选择器正在选择这些视频,而您的源选择器却没有。