You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用NodeJS与Puppeteer爬取Udemy站点的课程图片资源

Udemy课程封面爬取问题修复方案

核心问题原因

  1. 选择器错误:你当前选取的div.course-card--image-wrapper--1F9ny是图片外层容器,不是<img>标签本身,所以无法读取src属性返回null
  2. 懒加载未触发:Udemy课程列表使用图片懒加载策略,只有进入可视区域的图片才会加载资源,因此非可视区图片没有资源链接、截图时显示为黑色

修复后完整代码

const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth')
puppeteer.use(StealthPlugin());
const fs = require('fs/promises')
function sleep(ms)
{
    return new Promise(resolve => setTimeout(resolve, ms));
}
async function start()
{
    const browser = await puppeteer.launch({ headless: true });
    const page = await browser.newPage();
    await page.goto("https://www.udemy.com/pl/courses/development/web-development/?lang=pl&sort=popularity&persist_locale=&locale=pl_PL", {
        waitUntil: 'networkidle2'
    });
    await sleep(2000);

    // 新增自动滚动逻辑,触发所有图片懒加载
    let scrollHeight = await page.evaluate(() => document.body.scrollHeight);
    let currentScroll = 0;
    const scrollStep = 800; // 每次滚动800px,可根据视口调整
    while (currentScroll < scrollHeight) {
        await page.evaluate((step) => window.scrollBy(0, step), scrollStep);
        await sleep(1000); // 停顿等待懒加载资源加载
        currentScroll += scrollStep;
        // 重新获取滚动高度,适配动态加载的课程列表
        scrollHeight = await page.evaluate(() => document.body.scrollHeight);
    }
    // 滚动完成后回到顶部
    await page.evaluate(() => window.scrollTo(0, 0));
    await sleep(1000);

    const names = await page.evaluate(() => {
        return Array.from(document.querySelectorAll(".course-list--container--3zXPS div.udlite-focus-visible-target.udlite-heading-md.course-card--course-title--vVEjC")).map(x => x.textContent)
    })
    const images = await page.evaluate(() => {
        // 修正选择器,选中容器内的img标签
        return Array.from(
            document.querySelectorAll(".course-list--container--3zXPS div.course-card--image-wrapper--1F9ny img")
        ).map((image) => image.getAttribute("src"));
    });


    let m = ";";
    for (let i = 0; i < names.length; i++)
    {
        names[i] = i+m+names[i]+m+images[i]
    }
    await fs.writeFile("courses.txt", names.join("\r\n"))
    await page.screenshot({ path: "udemy.png", fullPage: true });
    await browser.close();
}
start()

主要修改说明

  • 给page.goto新增了waitUntil: 'networkidle2'配置,确保页面基础资源加载完成后再执行后续操作
  • 新增了自动滚动逻辑,逐段滚动页面触发所有图片的懒加载,同时适配页面动态加载的更多课程内容
  • 修正了图片元素选择器,直接选取图片容器下的<img>标签读取src属性,可正常拿到封面图链接
  • 所有图片加载完成后再截图,不会出现非可视区图片涂黑的问题

内容的提问来源于stack exchange,提问作者Grt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 08:45:08