前言
作为一个前端程序员,领导问我能不能搞爬虫?那必须能:
本文用Node.js快速开发一个网页简单爬虫,并将数据导出为Excel。
代码10分钟,运行3分钟导出,过程非常丝滑。
技术栈选择
- Node.js : 运行环境; axios : 网络请求; cheerio: HTML解析
- iconv-lite : 编码转换; xlsx: Excel文件处理
node爬虫都有现成的库,不需要去手动造轮子~
2. 爬虫实现
2.1 基本原理
网页爬虫的基本原理是:
- 发送HTTP请求获取网页内容
- 解析HTML提取需要的数据
- 保存数据
场景:领导给的网页如下,一个分页列表,需要爬取日期,作者,文章标题,内容;咱一看这么简单的需求,那不手到擒来。
思路分析: 数据是从list中分页返回的,第一反应是去获取list的接口,看有没有对应的字段。
network打开一看结构,发现没有信息,返回的是一个html,内容如下:
js
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-134497917-2"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-134497917-2');
</script>
这段代码并没有有用信息,是网站用来收集追踪点击量等用户信息的
那我们继续点开文章看,多点了几个之后发现文章的链接参数只有id再变化,
点到最后一个列表是1197 最新一个是35348,那这不妥了嘛,
循环替换id 获取网页html结构,根据结构获取出想要的标签
nice 开搞:
新建一个test.js文件 安装爬虫所需要的依赖:
npm install axios cheerio iconv-lite 这三个包的用途是:
-
axios - 用于发送 HTTP 请求
-
cheerio - 用于解析 HTML 并进行类似 jQuery 的 DOM 操作
-
iconv-lite - 用于处理字符编码转换(这里用于将 GB2312 编码转换为 UTF-8)
2.2 核心代码实现
test.js
const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const iconv = require('iconv-lite');
async function scrapeWebpage(id) {
try {
const url = `https://www.chasedream.com/show.aspx?id=${id}&cid=28`;
const response = await axios.get(url, {
responseType: 'arraybuffer'
});
// 将GB2312编码的响应转换为UTF-8
const html = iconv.decode(response.data, 'gb2312');
const $ = cheerio.load(html);
// 提取标题
const title = $('.aTitle').text().trim();
// 从表格第一个td中提取日期
const date = $('table[width="100%"][align="center"] tr:first-child td:first-child').text().trim();
const author = $('table[width="100%"][align="center"] tr:first-child td:nth-child(3)').text().trim();
// 提取内容
const content = $('#content').text().trim();
return {
id,
title,
date,
author,
content
};
} catch (error) {
console.error(`爬取ID ${id}时出错:`, error.message);
return null;
}
}
async function scrapeRange() {
const results = [];
for (let id = 1179; id <= 35394; id++) {
console.log(`正在爬取ID: ${id}`);
const result = await scrapeWebpage(id);
if (result) {
results.push(result);
}
await new Promise(resolve => setTimeout(resolve, 5));
}
fs.writeFileSync('chasedream2.json', JSON.stringify(results, null, 2), 'utf8');
console.log('爬取完成。结果已保存到scrape_results.json');
}
scrapeRange();
代码解析:一共两个主要函数,scrapeRange() 用于遍历id ;scrapeWebpage实现具体的业务逻辑
1、scrapeRange() 函数
-
循环遍历 ID 范围(从 1179 到 35394)
-
对每个 ID 调用 scrapeWebpage 函数
-
收集所有成功抓取的结果
-
在每次请求之间添加 5ms 的延迟(避免请求过于频繁)
-
最终将所有结果保存到 chasedream2.json 文件中
2、scrapeWebpage(id)
这个函数的作用是:
-
根据给定的 ID 构建 URL
-
发送 HTTP 请求获取页面内容
-
将 GB2312 编码的响应转换为 UTF-8
-
使用 cheerio 解析 HTML 并提取以下信息:
-
标题 (.aTitle)
-
发布日期 (从表格中提取)
-
作者信息
-
帖子内容 (#content)
这里具体的逻辑就看需要获取的内容,使用对应的选择器就能获取,必要的时候进行清理一下
最后获取到的数据再使用node的fs模块writeFileSync 生成json文件; 结果如下:
虽然领导没给咱提需求要excel,但是作为想进步的下属,那肯定贴心的为领导也备上一份excel:
3. 数据导出Excel
3.1 Excel导出实现
excel导出使用 XLSX依赖 npm install xlsx
javascript:excel.js
const XLSX = require('xlsx');
![image.png](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/5b8013653f6a44a0b495c145435f50c0~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5Y2B5Lmd5LiH6YeM:q75.awebp?rk3s=f64ab15b&x-expires=1734061157&x-signature=DCzgKQBMdXxRyQmI5eQTUowBC%2FY%3D)
// 读取JSON数据
const jsonData = JSON.parse(fs.readFileSync('scrape_results.json', 'utf8'));
// JSON转Excel工作表
const worksheet = XLSX.utils.json_to_sheet(jsonData);
// 设置格式
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
// 设置列宽
worksheet['!cols'] = [
{ wch: 20 }, // 第一列宽度
{ wch: 20 }, // 第二列宽度
{ wch: 20 }, // 第三列宽度
{ wch: 20 } // 第四列宽度
];
// 设置行高
const rowCount = jsonData.length + 1;
worksheet['!rows'] = Array(rowCount).fill({ hpt: 30 });
// 导出Excel
XLSX.writeFile(workbook, 'output.xlsx');
导出的同时在优化一下表格样式,搞定!5000条数据到手
导出优化建议:
- 设置适当的列宽和行高
- 添加文件占用检查
- 错误处理
给领导一发:
我已经能感受到了下次加工资必须有我!!!
后续:领导问能不能爬小红书(头一下子就大了.....)
4. 注意事项
- 请求频率控制: 添加适当的延时避免被封IP,我这简单网站没有反爬机制直接0.1ms
- 异常处理: 对于爬取过程中可增加日志,方便分析结果
- 数据清洗: 对提取的数据进行清洗和格式化
总结
通过Node.js实现网页爬虫其实并不复杂,关键是要理解基本原理并选择合适的工具库。本文介绍的方案虽然简单,但已经能满足大部分基础爬虫需求。希望这个例子能帮助大家快速上手网页爬虫开发!