18 KiB
招聘考试信息聚合系统 · 总计划书(设计稿 v0.1)
状态:设计/规划阶段,暂不开发。本文档用于锁定范围、对齐架构、暴露风险,并列出需你拍板的关键决策。 落点:作为 service.xpcool.com(Go 后端模块) + admin.xpcool.com(Vue 管理/可视化前端模块) 的一个功能模块。 默认地区:贵阳市;架构需天然支持全省 9 个市州 + 省直,便于后续扩展。
0. 文档约定
- 术语:发布主体(谁发的,可能是机关/事业单位/国企/央企/私企)、考试分类(公务员/事业单位/国企/央企/私企/其他)、公告(一条招聘考试信息)。两者解耦,才能支撑你想要的"按企业 + 按分类"双重筛选。
- 时间基线:2026-08-27。历史全量定义为"近 2 年"(2024-08 起)。
- 所有域名/接口形态均来自 2026-08 真实联网核查,标注【已核验】;其余为规划假设,需 POC 验证。
1. 业务目标与成功标准
你要做的事(复述对齐):
- 爬取贵州各地区官方渠道发布的招聘考试信息。
- 默认聚焦贵阳,支持多分类筛选:公务员、事业单位、国企、央企、私企等。
- 先做一次近两年全量历史回溯,再每天增量抓取最新。
- 每天早上诉Bark 推送给你。
- 在 admin 里做可视化展示 + 数据分析。
成功标准(建议,可调整):
- 贵阳 + 公务员/事业单位/国企/央企 四类,官方源覆盖率 ≥ 90%,公告从发布到入库延迟 < 24h。
- 每日早上推送稳定到达(失败有兜底告警)。
- 去重准确率 ≥ 99%(同一公告多站转发不重复计)。
- admin 可对任意"地区 × 分类 × 时间"组合做筛选与趋势分析。
2. 数据源调研(贵州真实官方渠道)【已核验 2026-08】
2.1 省级统一门户
| 名称 | 域名 | 形态 | 覆盖分类 | 备注 |
|---|---|---|---|---|
| 贵州人事考试信息网 | gzrsks.com.cn【已核验】 |
SPA(hash 路由) | 公务员招录、事业单位招聘、资格考试、"三支一扶" | 全省最核心门户,但是前端渲染,需找底层 JSON 接口或用 headless 渲染 |
| 贵州省公务员局 | gzzzb.gov.cn【已核验】 |
静态列表页 | 公务员(省/市/县/乡四级联考、遴选) | 公告 + 职位表,链接常回链到 gzrsks 专题页 |
| 贵州人力资源社会保障网 | rst.guizhou.gov.cn |
静态 | 省直事业单位、人才引进 | 省本级发布渠道 |
2.2 贵阳市(默认地区,已核验可抓)
| 名称 | 域名 | 栏目/路径 | 覆盖 |
|---|---|---|---|
| 贵阳市人力资源和社会保障局 | rsj.guiyang.gov.cn【已核验】 |
rszk 人事招考 |
事业单位、教师、卫健、"三支一扶"、局属单位 |
| 贵阳市人民政府 | guiyang.gov.cn【已核验】 |
人事招考 / 招聘信息 | 转发市直单位招聘公告 |
2.3 其他地区(9 市州 + 省直,需 POC 验证)
架构预留,首批不做。后续按"市州人社局官网 + 市政府门户人事招考栏目"模式复制: 遵义、六盘水、安顺、毕节、铜仁、黔东南州、黔南州、黔西南州 + 省直(已在 2.1 覆盖)。
注意:部分市州门户为静态、部分也是 SPA,难度不一,需逐个 POC。
2.4 国企 / 央企【已核验】
| 渠道 | 域名 / 地址 | 备注 |
|---|---|---|
| 贵州省国资委国资央企招聘平台 | cujiuye.iguopin.com【已核验】 |
243 家国企夏季招聘(茅台、旅投、磷化、乌江能源、盐业、路桥…),规模大 |
| 中国贵州茅台集团 | moutaichina.com / moutai.com.cn【已核验】 |
高层次人才/应届引才,附件多(xlsx/docx) |
| 贵州电网 | 南网招聘系统 zhaopin.csg.cn【已核验】 |
公告常经 gov 站/聚合站转发,源头在系统内需登录 |
| 其他省属/在黔央企 | 各集团官网"人才招聘"栏目 | 名单见国资委平台,逐一登记 |
2.5 私企 / 其他 —— 明显的覆盖缺口,需你决策
- 纯私企几乎不在政府官网发"招聘考试"。其信息散落在:① 企业自己官网"招聘/校园招聘"栏目;② 招聘聚合站(智联、BOSS、猎聘、高校人才网等);③ 微信公众号。
- 建议分期:首批只做官方/半官方源(公务员/事业/国企/央企),"私企"作为二期,来源改为"知名民营企业官网招聘页 + 1~2 个可信聚合站",并明确标注来源为非官方。
- 风险:聚合站有版权与反爬限制,且信息噪声大,需更强的清洗与去重。
2.6 数据源分级(决定技术难度)
- A 类 静态列表页:goquery 直接解析(如 rsj.guiyang.gov.cn)。最易。
- B 类 SPA / JS 渲染:需定位底层 API 或 headless 渲染(如 gzrsks.com.cn)。最难,是工期主要风险点。
- C 类 需登录/验证码:如南网招聘系统、部分企业内网。首批排除,人工或后续对接。
- D 类 附件型:公告正文在 PDF/Word(如茅台 xlsx 岗位表)。需附件解析抽取关键字段。
3. 整体技术架构
3.1 部署拓扑(复用现有底座)
- 复用腾讯云
193.112.118.168(CentOS Stream,SSH 22025,账号 xxcool)。 - 复用 Docker +
xpcool-net网络 + 宿主机 Nginx。 - 后端模块挂进现有
service.xpcool.com:new容器(已有127.0.0.1:10100:10100、envGF_GCFG_ENV=prod+DB_DSN(须带mysql:前缀) +JWT_SECRET,且容器内必须有manifest/config/config.yaml)。 - 前端模块挂进
admin.xpcool.com,Nginx 落点/data/www/admin.xpcool.com/。 - Bark:建议与现有服务同机或独立容器部署(见 §6)。
3.2 模块划分
[数据源网站]
│ (HTTP / API / headless)
▼
[Crawler 爬虫引擎] ── 调度器(cron, 每日凌晨) ──┐
│ 去重/字段抽取/附件解析 │
▼ │
[MySQL 存储] ◀── 读写 ── [service 后端 API 模块 /recruitment/*]
│ │
│ [admin 前端模块]
│ │
[Bark 推送器] ◀── 每日早报任务 ────────────────┘
3.3 技术选型(对齐现有底座)
- 后端:Go + com.lib.gf.v2 + com.lib.v2(与 service 同源,复用 ORM/配置/日志/JWT)。新增
recruitment模块包。 - 前端:Vue + TDesign(admin 现有约定,写组件前先走 TDesign MCP 查官方文档)。
- 存储:MySQL(复用 service 库,或独立
recruitment库——见决策点)。 - 调度:Go 内置 cron(如 gocron)常驻于 service 进程;或系统 crontab 调内部 API(二选一)。
- 动态渲染:Playwright(Python/Node sidecar 或 CLI),仅 B 类 SPA 按需调用,避免全量上浏览器。
4. 数据模型设计(草案)
发布主体与考试分类解耦,支撑"按企业 + 按分类"双重筛选。
recruitment_info(公告主表)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | bigint PK | |
| title | varchar | 标题 |
| source_id | bigint FK | 数据源(crawl_source) |
| org_id | bigint FK | 发布主体(organization) |
| category | tinyint | 考试分类(1公务员/2事业单位/3国企/4央企/5私企/6其他) |
| region | varchar | 地区(贵阳/省直/遵义…),支持多级 |
| publish_date | date | 发布日期 |
| deadline | date NULL | 报名/截止日期(抽取) |
| exam_date | date NULL | 笔试日期(抽取) |
| url | varchar | 原文链接(唯一性依据之一) |
| content | longtext | 正文/摘要 |
| attachments | json NULL | 附件链接与解析结果 |
| status | tinyint | 0有效/1已更正/2已失效/3已删除 |
| fingerprint | varchar | 去重指纹 |
| created_at / updated_at | datetime |
organization(发布主体):id, name, type(机关/事业/国企/央企/私企/其他), official_site, region。 crawl_source(数据源配置):id, name, base_url, type(A/B/C/D), list_selector/api_path, cron_expr, enabled, last_success_at, fail_count。 crawl_log(抓取日志):id, source_id, run_at, fetched, new, updated, error。 push_subscription(推送订阅):id, device_key(Bark), regions(json), categories(json), only_new(bool), push_time。 push_log(推送记录):id, subscription_id, push_at, title, body, result。
索引:url(唯一)、fingerprint(唯一)、(region, category, publish_date) 复合索引支撑筛选与趋势。
5. 爬虫设计
5.1 抓取策略
- 全量历史(首跑):对每个 A/B/C 类源,按列表分页从当前回溯到 2024-08;D 类附件一并下载解析。
- 增量(每日):每日凌晨对全部 enabled 源巡检列表前 N 页(覆盖当天新发),入库新公告 / 更新已存在公告的 status(官网更正/取消时标记而非硬删)。
5.2 解析方式(按源分级)
- A 类:goquery CSS 选择器解析列表 + 详情。
- B 类 SPA:先抓 XHR/JSON(浏览器 DevTools 看接口);拿不到再走 Playwright 渲染后抽取。
- D 类:下载 PDF/Word → 文本抽取 → 正则提"报名/笔试/截止"日期与岗位数。
5.3 去重与更新
- 指纹 =
hash(source_id + normalize(title) + publish_date + url);同公告多站转发视为多条不同来源记录但关联同一group_key(如hash(title+publish_date)),前端可按 group 聚合展示"多家来源"。 - 更新检测:再次抓取时比对 content 哈希,变化则更新 + 记 crawl_log。
5.4 反爬与稳定性
- 统一限速(每源间隔 ≥ 2~5s)、随机 UA、超时重试(指数退避)、失败计数。
- 连续失败 ≥ 阈值:标记源异常 + Bark/邮件告警(避免静默失效)。
- 代理池(可选,IP 被封时启用)。
5.5 字段抽取难点
- 截止/笔试日期、招聘人数、学历要求:正文正则 + 模板兜底;首批对样本做人工校验,调置信度。
- 地区推断:优先取源所属地区,正文含"贵阳/遵义…"可校正。
5.6 调度
- 每日 02:00–05:00 增量巡检(错峰、规避官网高峰)。
- 首跑全量可手动触发 + 分批(按源、按月份)防止单次过长。
6. Bark 每日推送设计
6.1 自建 vs 公共(决策点)
- 公共
api.day.app:零部署,POSThttps://api.day.app/push{device_key,title,body,group,url}即可。代价:通知文本经第三方。推荐先走公共版跑通,再决定是否自建。 - 自建
finab/bark-server(Docker):隐私可控,但必须配置 APNs 证书(p8+KeyID+TeamID)才能真正推到 iPhone,且需域名+HTTPS。运维成本更高。 - 你的腾讯云同机部署可行(另开端口或子域名 + Caddy 自动证书)。
6.2 每日早报模板(建议)
【贵州招聘早报 · 2026-08-27 · 贵阳】
昨日新增:公务员 0 · 事业单位 3 · 国企 1 · 央企 0 · 私企 0
🔥 重点关注:
· 贵阳贵安2026事业单位面试公告(截止 08-30)
· 贵州电网春招补录(截止 09-05)
👉 点击查看详情:https://admin.xpcool.com/recruitment
- 用
group=recruit_daily分组;level=active;url深链到 admin 对应筛选页。
6.3 订阅过滤
- 按
push_subscription:可配置"仅贵阳""仅公务员+事业单位""仅推送新公告"。 - 多设备/多人可扩展(家人/同事各一 key)。
6.4 时机与兜底
- 默认 每天早上 08:00 推送(可配置)。
- 推送失败:记录 push_log + 重试 1 次 + 仍失败则 Bark 告警自身(用另一个 key/渠道)。
7. 可视化与数据分析(admin 模块)
- 仪表盘:总公告数、近 30 天新增、按分类占比环图、按地区柱状、今日/昨日新增卡片。
- 列表 + 筛选:地区(多级)、分类(多选)、发布时间范围、关键词(标题/正文/单位全文检索)、状态(有效/已失效);表格 + 详情抽屉(原文链接、附件、多来源聚合)。
- 趋势分析:按月/按地区/按分类的时间序列折线;支持导出 Excel/CSV。
- 爬虫运维面板:各源最后成功时间、失败次数、今日抓取量、手动触发按钮、日志查看。
- 权限:复用 admin 现有 JWT +
admin_menu(type=2) 路由注册(path 须与实际前端路由匹配,历史踩坑点)。
8. 你没想到 / 容易踩的坑(重点补充)
法律与合规
- robots.txt 与版权:政府官网通常允许转载但需注明来源;逐站评估使用条款,正文展示标注"来源:XXX"并链回原文。
- 个人隐私边界:只聚合"公告本身",绝不抓取报名系统表单/考生个人信息。
- 数据使用边界:仅作个人/内部信息聚合展示,不篡改、不商业化转售。
反爬与可用性(最大的技术风险) 4. SPA 抓不到正文:gzrsks.com.cn 是 hash 路由 SPA,纯 HTTP 拿不到内容——必须先做接口逆向或上 Playwright,这是首跑 POC 的第一关。 5. IP 被封 / 频率限制:需限速、随机 UA、代理池、退避重试。 6. 网站改版:模板一变解析器即失效,需"解析失败即告警"而非静默。 7. 登录/验证码源:南网招聘系统等首批排除,避免卡住整体进度。
数据质量
8. 去重准确性:同公告多站转发 ≠ 重复;用 group_key 聚合、用 fingerprint 防真重复。
9. 公告变更/撤回:官网更正或取消招聘,应标记 status(已更正/已失效),不要硬删,否则趋势断裂。
10. 日期/人数抽取易错:正文格式多样,首批必须人工抽检样本校准正则。
11. 附件解析:PDF/Word 岗位表里的关键信息(特别是茅台类)需单独抽取管线。
覆盖与完整性 12. 历史全量能否拿到:部分官网旧公告会被归档或删除,近两年回溯可能不完整;POC 阶段就要验证"能回溯到多久"。 13. 增量漏抓补偿:某天爬虫失败,次日需补抓(而非只抓"今天"),设计成"按发布日期窗口回扫"。 14. 新源发现机制:新出现的发布渠道如何纳入——建"候选源登记 + 人工审核"流程,而非自动信任。 15. 私企覆盖缺口:无官方源,需明确二期方案与来源可信度标注(见 §2.5)。
运维与告警 16. 爬虫失败必须告警:某源连续失败 N 次 → Bark/邮件通知,否则你以为在跑其实已挂。 17. 推送本身要可观测:push_log + 失败重试 + 独立告警通道。
产品与体验 18. 搜索是刚需:标题/正文/单位全文检索,否则数据多了找不到。 19. 收藏/关注:可标记"关注的单位/分类",推送可只推关注的。 20. 数据导出:Excel/CSV 供你自己分析。 21. 移动端查看:admin 是否要移动适配(你主要手机看推送,但详情可能在 admin)。
集成与部署
22. 与现有 service/admin 权限体系对接:复用 JWT、admin_menu 路由(type=2 path 匹配历史坑)、xpcool-net 网络、env(DB_DSN 带 mysql: 前缀、JWT_SECRET)。
23. 爬虫常驻 vs 独立容器:放进 service 进程省运维面,但 SPA 渲染要 Playwright sidecar——资源与隔离如何权衡(见决策点)。
24. 配置外置:爬虫源、Bark key、推送时间、地区默认走配置/环境变量,不写死代码。
技术决策点(待你拍板) 25. 爬虫语言/形态:纯 Go 适配器 vs Python 爬虫微服务写同一库?Go 同源易部署但 SPA/Playwright 生态弱;Python 爬虫生态成熟但多一个服务。 26. 存储:复用 service 库 vs 独立 recruitment 库?独立库隔离风险、便于单独备份与扩容。
9. 分阶段实施计划(开发期,本节为后续开发用)
- 阶段 0 · 数据源 POC(约 1 周):对贵阳 4 类 + gzrsks SPA 做可行性验证,拿到真实接口/选择器,确认近两年可回溯性。POC 不过则方案需调整。
- 阶段 1 · 数据模型 + 贵阳 MVP(公务员/事业单位):建表、Go 爬虫适配器(A 类优先)、基础列表 API、admin 列表页。
- 阶段 2 · 全量历史回溯:跑近两年全量,去重与字段校准,人工抽检。
- 阶段 3 · 增量 + Bark 每日推送:调度器 + 推送器 + 订阅过滤 + 失败告警。
- 阶段 4 · admin 可视化与分析:仪表盘、趋势图、筛选增强、爬虫运维面板、权限接入。
- 阶段 5 · 扩展:国企/央企源、私企二期、全省 9 市州、搜索/收藏/导出。
每阶段结束有"冒烟验证 + 数据抽检报告",再进下一阶段(契合你一贯的"非侵入、最小改动、迭代"偏好)。
10. 需你拍板的关键问题(Decision Points)
- 私企范围:首批只做官方/半官方(公务员/事业/国企/央企),私企放二期——可以吗?
- Bark:先公共
api.day.app跑通,还是直接自建?(需你提供 APNs 证书或授权我部署) - 爬虫形态:纯 Go 适配器(推荐,运维面小)还是 Python 微服务(SPA 处理强)?
- 存储:复用 service 库 还是 独立 recruitment 库?
- 默认推送时间:每天早上几点?(建议 08:00)
- 是否要移动端适配 admin:还是推送里给深链、电脑看详情即可?
- 推送粒度:每日汇总早报,还是"有新公告实时推"?(建议每日汇总,避免打扰)
11. 附录:接口草图(仅供讨论)
GET /api/service/admin/recruitment/list?region=贵阳&category=2&from=2026-08-01&q=教师
GET /api/service/admin/recruitment/stats?range=30d
GET /api/service/admin/recruitment/sources # 爬虫源状态
POST /api/service/admin/recruitment/crawl/trigger # 手动触发
POST /api/service/admin/recruitment/push/test # 测试 Bark
本文档为设计稿,待你确认决策点后进入阶段 0 POC。