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

使用JavaScript实现多页网站爬取并导出CSV/Excel的问题求助

解决方案:多页爬取并导出CSV/Excel

步骤1:安装额外依赖

除已有的axios、cheerio、express外,还需安装处理文件导出的包:

npm install csv-writer xlsx

步骤2:完整代码实现

const PORT = 8000;
const axios = require('axios');
const cheerio = require('cheerio');
const express = require('express');
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
const XLSX = require('xlsx');

const app = express();

// 爬取单页数据的函数
async function scrapePage(pageNum) {
  const url = `https://www.taneps.go.tz/epps/viewAllAwardedContracts.do?d-3998960-p=${pageNum}&selectedItem=viewAllAwardedContracts.do&T01_ps=100`;
  try {
    const response = await axios({
      url,
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
      }
    });
    const html = response.data;
    const $ = cheerio.load(html);
    const rows = [];

    // 提取表头(仅第一页)
    let headers = [];
    if (pageNum === 1) {
      $('#T01 thead th').each((i, el) => {
        headers.push($(el).text().trim());
      });
    }

    // 提取表格行数据
    $('#T01 tbody tr').each((i, el) => {
      const row = {};
      $(el).find('td').each((j, cell) => {
        row[headers[j]] = $(cell).text().trim();
      });
      rows.push(row);
    });

    return { headers, rows };
  } catch (err) {
    console.error(`爬取第${pageNum}页失败:`, err);
    return { headers: [], rows: [] };
  }
}

// 获取总页数
async function getTotalPages() {
  const url = 'https://www.taneps.go.tz/epps/viewAllAwardedContracts.do?d-3998960-p=1&selectedItem=viewAllAwardedContracts.do&T01_ps=100';
  try {
    const response = await axios({
      url,
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
      }
    });
    const html = response.data;
    const $ = cheerio.load(html);
    // 解析分页信息中的总页数,需根据页面实际结构调整选择器
    const pageInfo = $('.paginationInfo').text().trim();
    const totalPagesMatch = pageInfo.match(/of (\d+)/);
    if (!totalPagesMatch) return 1;
    return parseInt(totalPagesMatch[1]);
  } catch (err) {
    console.error('获取总页数失败:', err);
    return 1; // 默认仅爬第一页
  }
}

// 主爬取函数:爬取所有页面并导出文件
async function scrapeAllPages() {
  const totalPages = await getTotalPages();
  console.log(`开始爬取,共${totalPages}页`);

  let allData = [];
  let headers = [];

  // 循环爬取每一页,添加延迟避免反爬
  for (let page = 1; page <= totalPages; page++) {
    console.log(`正在爬取第${page}页`);
    const { headers: pageHeaders, rows } = await scrapePage(page);
    if (page === 1) headers = pageHeaders;
    allData.push(...rows);
    // 每页间隔1秒,可根据情况调整
    await new Promise(resolve => setTimeout(resolve, 1000));
  }

  // 导出CSV文件
  if (allData.length > 0) {
    const csvWriter = createCsvWriter({
      path: 'awarded_contracts.csv',
      header: headers.map(header => ({ id: header, title: header }))
    });
    await csvWriter.writeRecords(allData);
    console.log('CSV文件已导出: awarded_contracts.csv');

    // 导出Excel文件(可选)
    const worksheet = XLSX.utils.json_to_sheet(allData);
    const workbook = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(workbook, worksheet, 'Awarded Contracts');
    XLSX.writeFile(workbook, 'awarded_contracts.xlsx');
    console.log('Excel文件已导出: awarded_contracts.xlsx');
  } else {
    console.log('未爬取到任何数据');
  }
}

// 启动服务器并开始爬取
app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
  scrapeAllPages();
});

关键改进点说明

  • 多页爬取:通过URL中的d-3998960-p参数控制页码,先获取总页数再循环爬取每一页。
  • 数据提取优化:不再提取整个表格的文本,而是解析表头和每一行的单元格内容,保证导出的CSV/Excel结构清晰。
  • 反爬处理:添加User-Agent请求头,并且在分页爬取时加入延迟,降低被网站拦截的风险。
  • 文件导出:使用csv-writer生成CSV文件,xlsx生成Excel文件,两种格式可选。

注意事项

  • 如果分页信息的选择器.paginationInfo无效,需要打开目标网站的开发者工具,找到实际的分页信息元素来调整选择器。
  • 如果爬取过程中出现请求失败,可能是网站的反爬机制限制,可以适当延长延迟时间,或者添加更多请求头(如Referer)。
  • 大量数据爬取时,建议分批写入文件,避免内存占用过高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 23:45:34