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

Node.js中如何用for循环迭代URL实现多页HTML批量爬取

最简实现方案

核心逻辑非常直接:把单页爬取逻辑封装为可复用函数,通过for循环按页码生成目标URL,逐页爬取解析后汇总所有结果统一返回即可。注意异步请求必须做等待处理,否则会出现数据未爬完就提前返回响应的问题。


具体修改步骤

  • 移除原有写死的单页URL常量,新增基础URL前缀、最大爬取页码两个配置项,方便后续调整
  • 把单页的axios请求、cheerio解析逻辑抽成独立异步函数,入参为页码,返回当前页解析出的文章列表
  • 在/results路由的处理函数中加for循环,从页码1开始迭代到设定的最大页码,逐页调用爬取函数,把每一页的结果合并到总结果数组
  • 所有页面爬取完成后,再把汇总的总结果返回
  • 顺手修复原代码里的变量名冲突问题:原代码中解析文章链接时定义的url变量和外层URL变量重名,改成articleUrl避免污染

修改后可直接运行的完整代码

const PORT = 8000
const axios = require('axios')
const cheerio = require('cheerio')
const express = require('express')
const app = express()
const cors = require('cors')
app.use(cors())

// 配置项:按实际需求修改即可
const BASE_URL = 'https://www.example.com/'
const MAX_PAGE = 10 // 要爬取的最大页码
const REQUEST_INTERVAL = 500 // 每页爬取间隔(毫秒),避免请求太频繁被拦截

// 单页爬取解析逻辑封装
async function crawlSinglePage(pageNum) {
    try {
        const response = await axios(`${BASE_URL}${pageNum}`)
        const html = response.data
        const $ = cheerio.load(html)
        const pageArticles = []

        $('.fc-item__title', html).each(function () { 
            const title = $(this).text().trim()
            const articleUrl = $(this).find('a').attr('href')
            pageArticles.push({
                title,
                url: articleUrl,
                page: pageNum // 可选:标记内容来源页码,不需要可以删掉
            })
        })
        return pageArticles
    } catch (err) {
        console.log(`第${pageNum}页爬取失败:`, err.message)
        return [] // 单页出错不中断整体任务,返回空数组跳过该页
    }
}

app.get('/', function (req, res) {
    res.json('This is my parser')
})

app.get('/results', async (req, res) => {
    const allArticles = []
    // 逐页循环爬取
    for (let currentPage = 1; currentPage <= MAX_PAGE; currentPage++) {
        const pageData = await crawlSinglePage(currentPage)
        allArticles.push(...pageData)
        // 爬完一页等待指定间隔再爬下一页
        await new Promise(resolve => setTimeout(resolve, REQUEST_INTERVAL))
    }
    res.json(allArticles)
})

app.listen(PORT, () => console.log(`server running on PORT ${PORT}`))

可选扩展:自动识别终止页

如果你不想提前固定最大页码,想要爬到没有内容的页面就自动停止,只需要在循环内部加个判断即可:

for (let currentPage = 1; ; currentPage++) { // 不设循环上限
    const pageData = await crawlSinglePage(currentPage)
    // 当前页没有爬到内容,直接跳出循环终止爬取
    if (pageData.length === 0) break
    allArticles.push(...pageData)
    await new Promise(resolve => setTimeout(resolve, REQUEST_INTERVAL))
}

注意:如果追求爬取速度,可以把串行for循环改成Promise.all并发请求,但一定要控制并发数,否则短时间请求量过大很容易被目标站点封禁IP,新手直接用串行方案最稳定。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:15:52