JobData/AGENTS.md
2026-03-22 23:22:30 +08:00

175 lines
6.7 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.

# JobData - 招聘数据采集与统计分析平台
## 变更记录 (Changelog)
| 版本 | 日期 | 说明 |
|------|------|------|
| 初始化 | 2026-03-20 | 首次生成架构文档,覆盖全部四个核心模块 |
---
## 项目愿景
JobData 是一个面向招聘市场的全栈数据采集与分析平台。系统从三大主流招聘平台Boss 直聘、前程无忧、智联招聘)自动抓取职位与公司数据,统一存储到 ClickHouse 列式数据库,并通过 FastAPI 后端 + Vue3 前端提供数据查看、定向清洗、统计分析等能力。ECS 弹性实例管理模块支持在阿里云上按需批量启停爬虫节点。
---
## 架构总览
```
[招聘平台] [爬虫层] [后端 API] [数据库]
Boss直聘 ──► jobs_spider/boss/ ──► ┌── MySQL
前程无忧 ──► jobs_spider/qcwy/ ──► app (FastAPI) ──► └── ClickHouse
智联招聘 ──► jobs_spider/zhilian/ ──►
web (Vue3) ────────┘
(前端页面)
ecs_full_pipeline.py ──► 阿里云 ECS ──► 批量启动爬虫节点
```
**核心技术栈**
| 层次 | 技术 |
|------|------|
| 后端 | Python 3.13, FastAPI 0.111, Tortoise-ORM 0.23, APScheduler |
| 数据库(业务) | MySQL用户/权限/审计/关键词/Token |
| 数据库(采集) | ClickHouse职位/公司 JSON 原始数据 + 分析视图) |
| 爬虫 | requests / httpx / PlaywrightPython 脚本) |
| 前端 | Vue 3.3, Vite 4, Naive UI, Pinia, ECharts |
| 基础设施 | 阿里云 ECS按量抢占实例APScheduler 定时任务 |
---
## 模块结构图
```mermaid
graph TD
ROOT["(根) JobData"] --> APP["app - FastAPI 后端"]
ROOT --> WEB["web - Vue3 前端"]
ROOT --> SPIDER["jobs_spider - 平台爬虫"]
ROOT --> ECS["ecs_full_pipeline.py - ECS 批量部署"]
APP --> APP_API["app/api - 路由层"]
APP --> APP_SVC["app/services - 业务逻辑"]
APP --> APP_CORE["app/core - 框架核心"]
APP --> APP_MODELS["app/models - ORM 模型"]
APP --> APP_REPO["app/repositories - 数据仓库"]
SPIDER --> SP_BOSS["jobs_spider/boss"]
SPIDER --> SP_QCWY["jobs_spider/qcwy"]
SPIDER --> SP_ZL["jobs_spider/zhilian"]
click APP "./app/AGENTS.md" "查看 app 模块文档"
click WEB "./web/AGENTS.md" "查看 web 模块文档"
click SPIDER "./jobs_spider/AGENTS.md" "查看 jobs_spider 模块文档"
```
---
## 模块索引
| 模块路径 | 语言 | 职责简述 |
|----------|------|----------|
| `app/` | Python | FastAPI 后端,提供 REST API、权限管理、定时任务、数据入库与分析 |
| `web/` | Vue3/JS | 前端管理界面,数据展示、关键词管理、代理管理、数据清洗操作 |
| `jobs_spider/` | Python | 三大平台的爬虫脚本,独立运行,结果通过 HTTP 推送到后端 |
| `ecs_full_pipeline.py` | Python | 阿里云 ECS 实例批量创建/销毁/命令下发全流程脚本 |
| `reclean_qcwy_jobs.py` | Python | 前程无忧数据重清洗独立脚本 |
---
## 运行与开发
### 后端启动
```bash
# 安装依赖pipenv
pipenv install
# 开发模式(默认端口 999920 个 worker
python run.py
# 环境变量覆盖
APP_HOST=0.0.0.0 APP_PORT=9999 UVICORN_WORKERS=4 python run.py
```
**关键环境变量**
| 变量 | 默认值 | 说明 |
|------|--------|------|
| `APP_HOST` | `0.0.0.0` | 监听地址 |
| `APP_PORT` | `9999` | 监听端口 |
| `UVICORN_WORKERS` | `20` | Worker 数量 |
| `CLICKHOUSE_HOST` | `121.4.126.241` | ClickHouse 地址(需修改为实际地址) |
| `CLICKHOUSE_USER` / `CLICKHOUSE_PASS` | 见 config.py | ClickHouse 认证 |
| `SMTP_HOST` / `SMTP_USER` / `SMTP_PASS` | 见 config.py | 邮件告警配置 |
| `REPORT_ENDPOINT` | 空 | 统计结果 Webhook 上报地址 |
| `RUN_MIGRATIONS_ON_STARTUP` | `True` | 是否启动时自动迁移 |
| `INITIALIZE_SEED_DATA_ON_STARTUP` | `True` | 是否启动时初始化种子数据 |
> 安全警告:`config.py` 中 `SECRET_KEY`、数据库连接串、SMTP 密码均为硬编码默认值,生产环境必须通过环境变量覆盖。
### 前端启动
```bash
cd web
pnpm install
pnpm dev # 开发模式,默认 http://localhost:5173
pnpm build # 构建产物到 web/dist
```
### ECS 批量爬虫部署
```bash
# 需配置阿里云凭据(环境变量或 ~/.alibabacloud/credentials
python ecs_full_pipeline.py
```
---
## 定时任务
APScheduler 在应用启动时注册以下任务(`app/core/scheduler.py`
| 任务 ID | 频率 | 职责 |
|---------|------|------|
| `stats_job` | 每 6 小时 | 统计 ClickHouse 各表总量并通过邮件/Webhook 上报 |
| `ecs_full_pipeline` | 每 6 小时 | 调用 `ecs_full_pipeline.py` 批量刷新爬虫节点 |
| `ip_alert_job` | 每 10 分钟 | 检查 IP 上报异常并告警 |
| `company_cleaning_job` | 每 5 分钟 | 自动清洗待处理公司数据collect 50 + process 30 |
| `daily_cleanup_job` | 每天 00:05 | 清理历史任务运行记录 |
所有任务通过分布式文件锁(或可选 Redis 锁)保证多 Worker 下只执行一次。
---
## 测试策略
- 当前代码库**无自动化测试文件**(缺口:单元测试、集成测试均缺失)。
- 推荐补充:
1. `app/services/` 的 service 层单元测试(使用 `pytest` + `anyio`
2. `app/api/v1/` 的 API 集成测试(使用 `httpx.AsyncClient`
3. `jobs_spider/` 的数据解析函数单元测试
---
## 编码规范
- Python使用 `ruff`(已在 Pipfile 中),格式化用 `black`,排序用 `isort`
- 前端ESLint`@zclzone` + `@unocss` 规则集),`prettier` 格式化。
- 类型:后端强制 `pydantic` Schema 做入参校验;前端以 JS 为主(未启用严格 TS
- 日志:后端统一使用 `loguru`,结构化字段 `logger.info(...)` 方式输出。
---
## AI 使用指引
- 修改爬虫逻辑时,重点关注反爬机制:`SmartIPManager``IPAnomalyDetector``jobs_spider/boss/boos_api.py` 中实现,随机延迟至少 10 秒。
- 新增 API 路由后需同步在 `app/api/v1/__init__.py` 注册,并执行 `api_controller.refresh_api()` 更新权限表。
- ClickHouse 表结构变更在 `app/core/clickhouse_init.py` 中维护,**不走 Aerich 迁移**。
- MySQL 模型变更走 Aerich`aerich migrate && aerich upgrade`)。
- 前端新增页面需要在 `web/src/views/{模块}/route.js` 和后端 `init_menus()` 中同步注册菜单。
- `config.py` 中已硬编码真实 MySQL/ClickHouse 连接串和 SMTP 凭据,**提交代码前务必确认不泄露敏感信息**。