木偶操纵者没有从网站上抓取全部信息
puppeteer not scraping full information from website
我有一个 puppeteer 抓取算法,可以抓取 youtube 的图像 URL 视频源,但我当前的代码只打印 4 个输出字符串及其 URL 源,其余输出空字符串。为了检查错误是否仅与图像源有关,我还添加了用于抓取视频标题的代码,并且视频标题抓取代码打印了所有没有任何空字符串的标题。这是什么原因造成的?如何修复它以打印所有图像 URL 来源?我讲过图像源只打印 4 个字符串的一个潜在原因,这可能是因为 youtube 每行有 4 个缩略图,而木偶操纵者不知何故只读取 1 行然后为其他打印空字符串但我写的代码用于抓取视频标题会打印所有视频标题,这反驳了我的假设。任何帮助表示赞赏。提前致谢。
const puppeteer = require('puppeteer');
async function scrape(url) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, {timeout: 0});
const selector1 = 'ytd-thumbnail > a > yt-img-shadow > #img'
const src1 = await page.$$eval(selector1, elems => elems.map(el => el.src))
const selector2 = 'h3 > a > #video-title'
const src2 = await page.$$eval(selector2, elems => elems.map(el => el.textContent))
browser.close();
console.log({src1, src2})
}
scrape("http://www.youtube.com")
这是 Youtube 上的一种无限滚动 行为,可确保客户端浏览器仅在用户将项目滚动到视图中时才获取这些项目。您可以打开 DevTools 元素选项卡并调查最后(第 n 个)ytd-rich-item-renderer:nth-child(n)
。你会看到里面的yt-img-shadow
:
<yt-img-shadow
ftl-eligible=""
class="style-scope ytd-thumbnail no-transition empty"
style="background-color: transparent;">
<!--css-build:shady-->
<img id="img" class="style-scope yt-img-shadow" alt="" width="9999">
</yt-img-shadow>
然后向下滚动直到元素出现在视图中,内部 <img>
将被更改:
<yt-img-shadow
ftl-eligible=""
class="style-scope ytd-thumbnail no-transition"
style="background-color: transparent;"
loaded="">
<!--css-build:shady-->
<img id="img" class="style-scope yt-img-shadow" alt="" width="9999" src="https://i.ytimg.com/vi/_{id}/hqdefault.jpg?sqp={parameter}">
</yt-img-shadow>
Whosebug 上有 many answers 如何用 puppeteer 处理无限滚动。
很可能您需要使用 vanilla JS(例如 scrollTo) inside a page.evaluate
滚动到您想要的程度。
我有一个 puppeteer 抓取算法,可以抓取 youtube 的图像 URL 视频源,但我当前的代码只打印 4 个输出字符串及其 URL 源,其余输出空字符串。为了检查错误是否仅与图像源有关,我还添加了用于抓取视频标题的代码,并且视频标题抓取代码打印了所有没有任何空字符串的标题。这是什么原因造成的?如何修复它以打印所有图像 URL 来源?我讲过图像源只打印 4 个字符串的一个潜在原因,这可能是因为 youtube 每行有 4 个缩略图,而木偶操纵者不知何故只读取 1 行然后为其他打印空字符串但我写的代码用于抓取视频标题会打印所有视频标题,这反驳了我的假设。任何帮助表示赞赏。提前致谢。
const puppeteer = require('puppeteer');
async function scrape(url) {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url, {timeout: 0});
const selector1 = 'ytd-thumbnail > a > yt-img-shadow > #img'
const src1 = await page.$$eval(selector1, elems => elems.map(el => el.src))
const selector2 = 'h3 > a > #video-title'
const src2 = await page.$$eval(selector2, elems => elems.map(el => el.textContent))
browser.close();
console.log({src1, src2})
}
scrape("http://www.youtube.com")
这是 Youtube 上的一种无限滚动 行为,可确保客户端浏览器仅在用户将项目滚动到视图中时才获取这些项目。您可以打开 DevTools 元素选项卡并调查最后(第 n 个)ytd-rich-item-renderer:nth-child(n)
。你会看到里面的yt-img-shadow
:
<yt-img-shadow
ftl-eligible=""
class="style-scope ytd-thumbnail no-transition empty"
style="background-color: transparent;">
<!--css-build:shady-->
<img id="img" class="style-scope yt-img-shadow" alt="" width="9999">
</yt-img-shadow>
然后向下滚动直到元素出现在视图中,内部 <img>
将被更改:
<yt-img-shadow
ftl-eligible=""
class="style-scope ytd-thumbnail no-transition"
style="background-color: transparent;"
loaded="">
<!--css-build:shady-->
<img id="img" class="style-scope yt-img-shadow" alt="" width="9999" src="https://i.ytimg.com/vi/_{id}/hqdefault.jpg?sqp={parameter}">
</yt-img-shadow>
Whosebug 上有 many answers 如何用 puppeteer 处理无限滚动。
很可能您需要使用 vanilla JS(例如 scrollTo) inside a page.evaluate
滚动到您想要的程度。