6.7 KiB
6.7 KiB
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 / Playwright(Python 脚本) |
| 前端 | Vue 3.3, Vite 4, Naive UI, Pinia, ECharts |
| 基础设施 | 阿里云 ECS(按量抢占实例),APScheduler 定时任务 |
模块结构图
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 | 前程无忧数据重清洗独立脚本 |
运行与开发
后端启动
# 安装依赖(pipenv)
pipenv install
# 开发模式(默认端口 9999,20 个 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 密码均为硬编码默认值,生产环境必须通过环境变量覆盖。
前端启动
cd web
pnpm install
pnpm dev # 开发模式,默认 http://localhost:5173
pnpm build # 构建产物到 web/dist
ECS 批量爬虫部署
# 需配置阿里云凭据(环境变量或 ~/.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 下只执行一次。
测试策略
- 当前代码库无自动化测试文件(缺口:单元测试、集成测试均缺失)。
- 推荐补充:
app/services/的 service 层单元测试(使用pytest+anyio)app/api/v1/的 API 集成测试(使用httpx.AsyncClient)jobs_spider/的数据解析函数单元测试
编码规范
- Python:使用
ruff(已在 Pipfile 中),格式化用black,排序用isort。 - 前端:ESLint(
@zclzone+@unocss规则集),prettier格式化。 - 类型:后端强制
pydanticSchema 做入参校验;前端以 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 凭据,提交代码前务必确认不泄露敏感信息。