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

使用Node.js与Puppeteer抓取随机词时如何添加进度描述/进度条?

Puppeteer 抓取进度展示及代码优化方案

一、进度展示实现逻辑

当前代码为单次抓取流程,可将全流程拆分为固定节点,给每个节点分配对应进度占比,执行到对应节点时直接打印进度和状态,无头模式下终端会直接输出内容,清晰直观。如果后续要扩展为批量多次抓取,可以按总抓取次数计算百分比进度。
具体实现要点:

  • 拆分全流程为核心节点,对应进度占比:启动浏览器(10%) → 打开目标页面(25%) → 填充抓取参数(40%) → 等待结果加载(60%) → 解析页面内容(80%) → 写入本地文件(95%) → 完成任务(100%)
  • 每个节点执行完成后打印当前进度,可搭配简单字符进度条提升可读性
  • 所有关键步骤加异常捕获,出错时直接打印错误原因,方便无头模式下排查问题

二、代码规范优化点

  • 依赖声明统一放到代码顶部,不要在函数内部声明require
  • 移除冗余无用变量(原代码中定义的file = 'word.txt'未实际使用)
  • 修正writeFileSync的错误写法:同步写入方法没有回调参数,用try/catch捕获异常即可
  • 常量统一外置管理,后续修改参数不需要调整函数内部逻辑
  • 给所有异步操作加异常捕获,避免程序直接崩溃

三、修改后完整代码

// 依赖统一顶部声明
const puppeteer = require('puppeteer');
const fs = require('fs');

// 常量外置统一管理
const CONFIG = {
    TARGET_URL: 'https://www.sodacoffee.com/words/list-generator',
    GENERATE_BTN_SELECTOR: '#ctl00_ContentPane_btn',
    RESULT_COUNT_SELECTOR: '#ctl00_ContentPane_resultscounter',
    WORD_TABLE_SELECTOR: '#ctl00_ContentPane_GridView1 tbody tr',
    SCRAPE_COUNT_PER_TIME: 50,
    OUTPUT_FILE_PATH: './words.json',
    // 如需批量抓取可以新增这个参数
    // TOTAL_SCRAPE_TIMES: 10
}

async function launchSearch() {
    let progress = 0;
    // 打印进度的工具函数
    function printProgress(currentProgress, desc) {
        const barLength = 20;
        const filledBar = '='.repeat(Math.floor(currentProgress / 100 * barLength));
        const emptyBar = ' '.repeat(barLength - filledBar.length);
        console.log(`[${filledBar}${emptyBar}] ${currentProgress}% | ${desc}`);
    }

    let browser;
    try {
        // 1. 启动浏览器
        browser = await puppeteer.launch({
            // 无头模式直接改为'new'即可
            headless: 'new',
        });
        progress = 10;
        printProgress(progress, '浏览器启动完成');

        // 2. 打开目标页面
        const page = await browser.newPage();
        await page.goto(CONFIG.TARGET_URL);
        progress = 25;
        printProgress(progress, '目标页面加载完成');

        // 3. 填充抓取参数
        const numWordsScrape = await page.$(CONFIG.RESULT_COUNT_SELECTOR);
        await numWordsScrape.click();
        await numWordsScrape.type(String(CONFIG.SCRAPE_COUNT_PER_TIME));
        progress = 40;
        printProgress(progress, '抓取参数填充完成');

        // 4. 点击生成等待结果加载
        await Promise.all([
            page.waitForNavigation(),
            page.click(CONFIG.GENERATE_BTN_SELECTOR)
        ]);
        progress = 60;
        printProgress(progress, '结果页面加载完成');

        // 5. 解析页面内容
        const wordList = await page.evaluate((selector) => {
            return Array.from(document.querySelectorAll(selector))
                .map(elem => elem.innerText.trim());
        }, CONFIG.WORD_TABLE_SELECTOR);
        progress = 80;
        printProgress(progress, '页面内容解析完成');

        // 6. 写入本地文件
        fs.writeFileSync(CONFIG.OUTPUT_FILE_PATH, JSON.stringify(wordList, null, 2));
        progress = 95;
        printProgress(progress, '结果写入本地完成');

        // 完成
        progress = 100;
        printProgress(progress, '全部任务执行完成');
        console.log(`共抓取到${wordList.length}个词汇,已保存到${CONFIG.OUTPUT_FILE_PATH}`);

    } catch (err) {
        console.error(`任务执行出错:${err.message}`);
    } finally {
        if (browser) await browser.close();
    }
}

launchSearch();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:24:01