Files
tool-node/README.md
zhaojunlong f35d4575c8 ```
feat(server): 更新默认端口为 5000 并支持环境变量配置

- 将 Web 服务器默认端口从 3000 更改为 5000
- 支持通过环境变量 PORT 自定义端口
- 添加 dotenv 依赖以加载环境变量
- 更新 README.md 中的所有相关端口说明
- 配置文件 config.json 加入 .gitignore 以防止敏感信息泄露
- 前端 API 地址改为自动检测当前域名和端口,提升部署灵活性
```
2025-12-15 15:58:48 +08:00

537 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 南京公共工程建设中心 - 公告采集工具
一个用于采集南京公共工程建设中心公告信息的 Web 可视化工具,支持定时任务和邮件推送。
## 功能特性
- ✅ 采集公告列表(支持分页)
- ✅ 按时间范围智能采集
- ✅ 采集公告详情内容
- ✅ 智能提取预算金额
- ✅ 生成统计报告
- ✅ Web 可视化界面
- ✅ 导出 Word/Markdown 报告
- ✅ RESTful API 支持
-**定时任务自动采集**
-**邮件推送 HTML 报告**
-**Web 配置界面**
-**无需数据库,轻量部署**
## 快速开始
### 1. 安装依赖
```bash
npm install
```
### 2. 配置文件
首次使用需要创建配置文件:
```bash
# 复制示例配置文件
cp config.example.json config.json
# 编辑配置文件(或通过 Web 界面配置)
# 填写邮件服务器信息和定时任务设置
```
**配置文件说明:**
- `config.example.json` - 配置模板(不含敏感信息,可提交到 Git
- `config.json` - 实际配置(包含密码等敏感信息,已在 .gitignore 中忽略)
## 使用方法
### 1. 启动服务器
```bash
npm start
```
### 2. 访问界面
打开浏览器访问: **http://localhost:5000** (或您配置的端口)
### 3. 功能介绍
**公告列表标签**
- 快速查看所有公告
- 支持分页浏览
- 一键获取最新公告列表
**详情采集标签**
- 批量采集公告详情
- 支持按时间范围采集
- 自动提取预算金额
- 可自定义采集数量
**生成报告标签**
- 支持按时间范围生成报告
- 设置金额阈值筛选项目
- 实时统计项目信息
- 一键导出 Word/Markdown 报告
**定时任务标签** ⭐ 新增
- Web 界面配置定时任务
- 支持 Cron 表达式自定义执行时间
- 可选时间范围(今日/本周/本月)
- 设置金额阈值自动筛选
- 实时查看任务运行状态
- 立即测试运行功能
**邮件配置标签** ⭐ 新增
- Web 界面配置 SMTP 邮件服务
- 支持主流邮箱QQ、163、Gmail 等)
- 测试连接功能验证配置
- 支持多个收件人
- 自动发送精美 HTML 报告
## 报告示例
```markdown
# 南京公共工程建设项目报告
**生成时间**: 2025/12/12 11:00:03
## 统计摘要
- 总项目数: 10
- 超过 50 万元的项目: 3
- 总金额: 5395.50 万元
## 项目列表
### 1. 项目名称
- **发布日期**: 2025-12-12
- **发布时间**: 2025-12-12 10:35:00
- **预算金额**: 5000 万元
- **链接**: https://...
```
## API 接口文档
服务器启动后提供以下 RESTful API 接口:
### 1. 获取公告列表
```
GET /api/list?url=<列表页URL>&page=<页码>
```
参数:
- `url` (可选): 列表页 URL,默认为官网首页
- `page` (可选): 页码,默认为 1
### 2. 按时间范围获取列表
```
POST /api/list-daterange
Content-Type: application/json
{
"startDate": "2025-11-01",
"endDate": "2025-12-31",
"maxPages": 23
}
```
### 3. 批量获取详情
```
POST /api/details
Content-Type: application/json
{
"items": [{ "title": "...", "href": "...", "date": "..." }],
"limit": 10
}
```
### 4. 生成报告
```
POST /api/report
Content-Type: application/json
{
"url": "https://gjzx.nanjing.gov.cn/gggs/",
"limit": 15,
"threshold": 50
}
```
### 5. 按时间范围生成报告
```
POST /api/report-daterange
Content-Type: application/json
{
"startDate": "2025-11-01",
"endDate": "2025-12-31",
"threshold": 50,
"maxPages": 23
}
```
### 6. 获取配置
```
GET /api/config
```
返回当前配置信息(密码会被隐藏)
### 7. 更新配置
```
POST /api/config
Content-Type: application/json
{
"scheduler": {
"enabled": true,
"cronTime": "0 9 * * *",
"threshold": 100000,
"timeRange": "today"
},
"email": {
"smtpHost": "smtp.qq.com",
"smtpPort": 587,
"smtpUser": "your-email@qq.com",
"smtpPass": "your-password",
"recipients": "recipient@example.com"
}
}
```
### 8. 获取定时任务状态
```
GET /api/scheduler/status
```
### 9. 手动触发定时任务
```
POST /api/run-scheduled-task
```
## 定时任务配置
### 通过 Web 界面配置(推荐)
1. 访问 `http://localhost:5000` (或您配置的端口)
2. 切换到 **"定时任务"** 标签
3. 配置以下选项:
- **启用定时任务**:勾选启用
- **执行时间**:选择预设时间或自定义 Cron 表达式
- **时间范围**:今日/本周/本月
- **金额阈值**:设置最低金额(单位:万元)
4. 切换到 **"邮件配置"** 标签
5. 配置 SMTP 邮件服务器信息
6. 点击"测试连接"验证配置
7. 点击"保存配置",定时任务自动生效
### 通过配置文件
编辑 `config.json`
```json
{
"scheduler": {
"enabled": true, // 是否启用
"cronTime": "0 9 * * *", // Cron表达式每天9点
"threshold": 100000, // 金额阈值万元10亿
"description": "每天9点采集大于10亿的项目",
"timeRange": "today" // 采集范围: today/thisWeek/thisMonth
},
"email": {
"smtpHost": "smtp.qq.com", // SMTP服务器
"smtpPort": 587, // 端口
"smtpUser": "your@qq.com", // 发件邮箱
"smtpPass": "授权码", // QQ邮箱授权码
"recipients": "to@qq.com" // 收件人(多个用逗号分隔)
}
}
```
### Cron 表达式说明
格式:`分 时 日 月 周`
常用示例:
- `0 9 * * *` - 每天 9:00
- `0 9,18 * * *` - 每天 9:00 和 18:00
- `0 9 * * 1` - 每周一 9:00
- `0 9 1 * *` - 每月1号 9:00
- `0 */6 * * *` - 每 6 小时
### 邮件服务配置参考
**QQ 邮箱:**
- SMTP: `smtp.qq.com`
- 端口: `587`
- 密码: 使用授权码(在 QQ 邮箱设置中生成)
**163 邮箱:**
- SMTP: `smtp.163.com`
- 端口: `465`
- 密码: 使用授权码
**Gmail**
- SMTP: `smtp.gmail.com`
- 端口: `587`
- 需要开启"不够安全的应用访问"
## 服务器部署
### 方法 1使用 PM2推荐
```bash
# 安装 PM2
npm install -g pm2
# 启动服务
pm2 start src/server.js --name gjzx-scraper
# 查看状态
pm2 status
# 查看日志
pm2 logs gjzx-scraper
# 设置开机自启
pm2 startup
pm2 save
```
### 方法 2使用 systemd
创建服务文件 `/etc/systemd/system/gjzx-scraper.service`
```ini
[Unit]
Description=GJZX Scraper Service
After=network.target
[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/tool-node
ExecStart=/usr/bin/node src/server.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
启动服务:
```bash
sudo systemctl enable gjzx-scraper
sudo systemctl start gjzx-scraper
sudo systemctl status gjzx-scraper
```
### 注意事项
-**无需数据库**:项目采用无数据库架构,轻量部署
-**配置持久化**:所有配置保存在 `config.json` 文件中
-**进程保活**:使用 PM2 或 systemd 确保进程持续运行
- ⚠️ **防火墙**:确保配置的端口可访问(默认 5000
- ⚠️ **配置安全**:不要将 `config.json` 提交到公开仓库
## 技术栈
- **后端**: Node.js + Express
- **爬虫**: Axios + Cheerio
- **定时任务**: node-cron
- **邮件服务**: nodemailer
- **前端**: 原生 HTML/CSS/JavaScript
- **编码处理**: iconv-lite (支持 GBK/UTF-8)
- **文档导出**: docx.js
- **架构**: 无数据库设计
## 项目结构
```
.
├── src/
│ ├── server.js # Web服务器及API
│ ├── scheduler.js # 定时任务调度器
│ └── emailService.js # 邮件发送服务
├── public/
│ ├── index.html # Web界面
│ └── app.js # 前端逻辑
├── config.json # 配置文件不提交到Git
├── config.example.json # 配置示例
├── package.json
└── README.md
```
## 架构特点
### 无数据库设计
本项目采用**无数据库架构**,具有以下特点:
-**轻量部署**:无需安装和配置数据库
-**实时数据**:每次从源站实时抓取最新数据
-**配置简单**:只需配置 config.json 文件
-**邮件归档**:报告通过邮件发送,邮箱即为历史记录
-**低资源消耗**:内存占用小,适合小型服务器
### 数据流程
```
定时触发 → 抓取网站数据 → 解析提取 → 筛选过滤 → 生成报告 → 发送邮件
↑ ↓
└──────────────────── 配置文件 ──────────────────────────┘
```
## 注意事项
1. **采集速度**:已限制为每条延迟 500ms-1s避免请求过快
2. **域名支持**:仅支持 gjzx.nanjing.gov.cn 域名的详情页解析
3. **金额提取**:基于正则匹配,支持多种格式(预算金额、最高限价等)
4. **端口配置**Web 服务器默认端口 5000支持通过环境变量 PORT 修改
5. **智能停止**:按时间范围采集会在检测到所有公告早于起始日期时自动停止
6. **编码处理**:自动识别,支持 GBK 和 UTF-8 网页
7. **配置安全**config.json 包含敏感信息,已加入 .gitignore不要提交到公开仓库
8. **进程保活**:部署时使用 PM2 或 systemd 确保定时任务持续运行
## 核心功能说明
### 时间范围采集逻辑
按时间范围采集时,程序会:
1. 从第一页开始顺序采集
2. 检查每页公告的日期是否在指定范围内
3. 如果某页所有公告都早于起始日期,自动停止采集
4. 支持设置最大页数限制,避免过度采集
### 金额提取规则
支持识别以下格式:
- 预算金额: XX 万元
- 最高限价: XX 万元
- 预算: XX 万元
- 金额: XX 万元
- 直接数字: XX 万元
### 编码处理
自动识别网页编码:
- 优先读取 Content-Type 中的 charset
- 自动处理 GBK、GB2312 编码
- 默认使用 UTF-8
## 常见问题
### Q: 为什么采集速度比较慢?
A: 为了避免对服务器造成过大压力,程序限制了请求频率(每条延迟 500ms-1s。这是一个负责任的爬虫设计。
### Q: 如何采集指定日期范围的公告?
A: 在 Web 界面的"详情采集"和"生成报告"标签中勾选"按时间范围采集",然后输入起始和结束日期即可。
### Q: 导出的报告在哪里?
A: 点击"导出 Word"或"导出 Markdown"按钮后会自动下载到浏览器的默认下载目录。
### Q: 可以采集其他网站吗?
A: 需要修改 server.js 中的 BASE_URL 和相应的解析函数,因为不同网站的 HTML 结构不同。
### Q: 需要安装数据库吗?
A: **不需要!** 本项目采用无数据库架构,只需安装 Node.js 依赖即可运行。所有配置保存在 config.json 文件中,报告通过邮件发送。
### Q: 定时任务配置后不生效怎么办?
A: 请检查以下几点:
1. `config.json``scheduler.enabled` 是否为 `true`
2. 邮件配置是否正确SMTP 服务器、用户名、密码)
3. Node.js 进程是否持续运行(使用 PM2 查看状态)
4. 查看服务器日志是否有错误信息
### Q: 如何修改定时任务的执行时间?
A: 有两种方式:
1. **Web 界面**(推荐):访问网页,切换到"定时任务"标签,选择预设时间或自定义 Cron 表达式,点击保存
2. **配置文件**:编辑 `config.json` 中的 `scheduler.cronTime` 字段
### Q: 邮件发送失败怎么办?
A: 常见原因:
1. **QQ 邮箱**:需要使用授权码,不是登录密码(在 QQ 邮箱设置 → 账户 → POP3/SMTP 服务中生成)
2. **端口问题**QQ 邮箱使用 587某些邮箱可能需要 465SSL
3. **防火墙**:确保服务器可以访问 SMTP 端口
4. **测试连接**:在"邮件配置"标签中使用"测试连接"功能验证配置
### Q: 如何查看定时任务运行日志?
A: 如果使用 PM2 部署:
```bash
pm2 logs gjzx-scraper
```
如果使用 systemd
```bash
sudo journalctl -u gjzx-scraper -f
```
### Q: 服务器重启后定时任务还会运行吗?
A: 需要设置开机自启:
- **PM2 方式**:执行 `pm2 startup``pm2 save`
- **systemd 方式**:执行 `sudo systemctl enable gjzx-scraper`
### Q: 可以设置多个定时任务吗?
A: 当前版本只支持一个定时任务。如需多个任务,可以:
1. 使用 Cron 表达式设置多个时间点(如 `0 9,18 * * *` 表示每天 9:00 和 18:00
2. 部署多个实例,使用不同的配置文件和端口
## 更新日志
### v1.1.0 (2025-12-15)
- ✨ 新增定时任务功能node-cron
- ✨ 新增邮件推送服务nodemailer
- ✨ 新增 Web 配置界面(定时任务 + 邮件配置)
- ✨ 支持多时间范围(今日/本周/本月)
- ✨ 配置 API读取/更新配置)
- ✨ 定时任务状态查询
- ✨ 手动触发任务功能
- 📝 完善文档,新增部署指南
### v1.0.0 (2025-12-12)
- Web 可视化界面
- 支持按时间范围采集
- 支持分页浏览
- 支持导出 Word/Markdown 报告
- RESTful API 接口
- 自动编码识别
- 智能金额提取
## License
MIT