feat: add compliant data connectors and lineage

- add authorized nine-source crawler connectors with security controls and packaged schemas
- add the school internship contract to the vendor data standard center
- add bidirectional campus data-to-report lineage with gap ownership and remediation

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
lofyer
2026-08-24 16:28:01 +08:00
co-authored by factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
parent 92515928d9
commit 8dff9847e3
46 changed files with 6145 additions and 55 deletions
+166
View File
@@ -0,0 +1,166 @@
# 招聘数据源采集实现方案
> 调研基线:2026-08-24。站点条款、robots.txt、页面结构和合作接口可能随时变化,上线前必须重新复核并留存审批证据。
## 1. 实现目标
`admin-tools/crawler/` 负责把来源数据接入 Raw 与 Source 层,再映射到统一契约:
- 外部岗位来源输出 `JOB-SIGNAL V3.0`;
- 校内就业来源输出 `SCHOOL-EMPLOYMENT V2.2`;
- 校内实习来源输出 `SCHOOL-INTERNSHIP V2.1`;
- 原始响应只追加保存,标准记录、隔离记录和运行摘要分别输出;
- 每次运行携带任务编号、连接器版本、采集时间、来源 URL 和 SHA-256。
- 薪资上下限统一折算为税前月薪,同时保留源端 `salary_period` 作为折算证据。
它不是用于绕过站点控制的通用抓取工具。代码不包含验证码处理、登录模拟、浏览器指纹伪装、私有接口逆向、代理池轮换或访问限制规避。
## 2. 强制接入边界
每个外部来源必须同时满足:
1. 已取得适用于目标用途、字段范围和保存期限的书面授权,或确认存在允许该用途的开放许可;
2. 使用官方 API、授权数据包或明确允许自动访问的公开页面;
3. 运行时 robots.txt 允许当前 User-Agent 和 URL;
4. 来源域名在连接器 allowlist 中,禁止任意 URL 和内网地址;
5. 使用可识别的 User-Agent 和真实技术联系邮箱;
6. 遵守来源级请求速率、并发、时间窗、停止条件和数据保留策略;
7. 页面出现登录、验证码、访问验证、封禁提示或条款变化时立即停止,不尝试绕过。
校内来源必须基于学校授权的数据处理协议,使用只读账号、租户隔离和最小字段集。平台禁止接收姓名、身份证号、手机号和明文学号。
## 3. 九个来源的实现方式
| 来源代码 | 数据源 | 实现类 | 接入方式 | 默认网络状态 | 上线前置 |
|---|---|---|---|---|---|
| `BOSS` | BOSS直聘 | `BossConnector` | 官方合作 API 或授权 JSON/NDJSON 数据包 | 禁用 | 合作协议、接口文档、字段与留存授权 |
| `ZHAOPIN` | 智联招聘 | `ZhaopinConnector` | 官方合作 API 或授权 JSON/NDJSON 数据包 | 禁用 | 书面许可;不得使用匿名网页爬虫 |
| `BRZP` | 全国中小企业招聘平台 | `BrzpConnector` | 官方数据接口优先;经许可后可读取公开 JobPosting/列表页 | 禁用 | 来源审批、robots 通过、入口 URL 白名单 |
| `NCSS` | 国家大学生就业服务平台 | `NcssConnector` | 官方合作接口优先;经许可后可读取公开职位/专场页 | 禁用 | 来源审批、robots 通过、入口 URL 白名单 |
| `MOHRSS` | 中国公共招聘网 | `MohrssConnector` | 官方数据交换或提供单位授权数据;公开页面仅用于获准范围 | 禁用 | 对应提供单位或招聘单位授权 |
| `IGUOPIN` | 国聘 | `IguopinConnector` | 官方合作 API 或授权数据包 | 禁用 | 合作协议;不得逆向动态页面私有接口 |
| `HZRC` | 杭州人才网 | `HzrcConnector` | 官方合作接口或书面许可的数据包/公开页面 | 禁用 | 书面许可、低速策略、robots 通过 |
| `SCHOOL_EMPLOYMENT` | 校内就业管理系统 | `SchoolEmploymentConnector` | 只读数据库视图导出、API 或 NDJSON 文件 | 无公网访问 | 租户授权、字段映射、学生令牌化 |
| `SCHOOL_INTERNSHIP` | 校内实习管理系统 | `SchoolInternshipConnector` | 租户 API 或 NDJSON 文件 | 无公网访问 | 租户授权、字段映射、学生令牌化 |
“默认网络状态为禁用”表示仓库代码不会因为安装或定时任务误配置而直接访问来源。操作者必须显式传入来源授权确认、入口 URL 和联系邮箱;商业来源还必须提供授权 feed URL。
### 3.1 BOSS直聘
- 不实现账号登录、扫码、Cookie 复用、验证码识别或页面安全验证绕过;
- 不固化网页私有接口、签名算法或浏览器指纹;
- 连接器只读取合同约定的 API/feed,或离线处理授权交付的 JSON/NDJSON;
- 字段重点为岗位、企业、地区、薪资、职责、技能和源端状态。
### 3.2 智联招聘
- [智联平台用户服务协议](https://rd6.zhaopin.com/aboutus/legal/service) 对未经书面许可的爬虫、自动化脚本和数据抓取有限制;
- 因此 `ZhaopinConnector` 只允许授权 feed/API 和离线数据包,不提供匿名页面采集模式;
- 授权材料编号应写入部署配置和审计系统,不写入代码仓库。
### 3.3 全国中小企业招聘平台
- 官方入口为 [全国中小企业网上百日招聘服务平台](https://brzp.chinasme.cn/);
- 优先申请结构化数据交换;公开页面模式只解析标准 `JobPosting` JSON-LD 或经版本化配置确认的页面;
- 活动页和岗位页分开建立水位,避免每日重复抓取全部历史活动。
### 3.4 国家大学生就业服务平台
- 官方入口为 [国家大学生就业服务平台](https://www.ncss.cn/);
- 职位、实习、专场和联合招聘应分别分片;
- 只处理无需登录且获准自动访问的页面或官方合作接口,不采集求职者、简历和账号数据。
### 3.5 中国公共招聘网
- 官方入口为 [中国公共招聘网](http://job.mohrss.gov.cn/);
- 其[网站声明](http://www.job.mohrss.gov.cn/cjobs/jobfairinfo/wzsyzn)提示招聘信息转载需联系相应提供单位或招聘单位取得合法授权;
- 生产接入优先使用官方数据交换。页面连接器必须绑定具体授权范围,不得因站点可公开浏览就默认允许批量复制。
### 3.6 国聘
- 官方入口为 [国聘](https://www.iguopin.com/);
- 页面高度动态化时不逆向私有 JSON 接口,也不使用浏览器登录会话;
- 只接入官方合作 API、企业授权导出或离线数据包。
### 3.7 杭州人才网
- 官方入口为 [杭州人才网](https://www.hzrc.com/);
- 站内招聘活动页面存在“未经书面许可严禁转载和复制”提示,因此必须先取得许可;
- 即使获准,默认仍采用低并发、长间隔、延迟熔断和单分片重试,响应异常时停止而不是提升并发。
### 3.8 校内就业管理系统
- 不是网页爬虫,使用学校提供的只读视图、API 或标准文件;
- 来源记录在学校侧先生成不可逆 `student_token`;
- 连接器拒绝包含姓名、身份证、手机号、邮箱或明文学号的输入;
- 以 `tenant_id + source_record_id + source_updated_at` 形成增量和幂等边界。
### 3.9 校内实习管理系统
- 不是网页爬虫,使用租户 API 或标准文件;
- 只接收学生令牌、专业、企业、岗位、起止日期、状态、工资和业务评价;
- 单租户认证、任务、水位、Raw、隔离区和输出目录均独立;
- 不接收敏感附件,证据只保存学校系统内的引用编号。
## 4. 运行路径
```text
来源审批
→ probe(robots / allowlist / 内容类型 / 小样本结构)
→ collect(严格记录数、页面数、速率和时间上限)
→ raw snapshot(原始载荷 + 元数据 + SHA-256)
→ parse(来源字段)
→ normalize(JOB-SIGNAL / SCHOOL-*)
→ schema validate
→ standard.ndjson / quarantine.ndjson / summary.json
→ 质量门禁与候选版本
```
失败分类至少包括:
- `AUTHORIZATION_REQUIRED`:没有显式授权确认;
- `ROBOTS_DENIED`:robots.txt 不允许;
- `HOST_NOT_ALLOWED`:入口或重定向不在来源 allowlist;
- `PRIVATE_ADDRESS_BLOCKED`:域名解析到内网、回环或保留地址;
- `AUTH_OR_CHALLENGE`:登录、验证码或访问验证;
- `SOURCE_STRUCTURE_CHANGED`:页面或数据字段不满足版本化解析规则;
- `SCHEMA_VALIDATION_FAILED`:标准记录不满足目标契约;
- `PII_REJECTED`:校内输入包含禁止字段。
## 5. 输出和证据
每个任务目录:
```text
外部来源:output/<source>/<task-id>/
校内来源:output/<source>/<tenant-id>/<task-id>/
├── raw/
│ ├── <sha256>.<json|html|bin>
│ └── <sha256>.metadata.json
├── standard.ndjson
├── quarantine.ndjson
└── summary.json
```
安全要求:
- URL 中的 token、key、signature 等敏感查询参数在日志和元数据中脱敏;
- Authorization、Cookie 和代理凭据仅从环境变量读取,不写入 Raw、日志或异常文本;
- 原始页面不得包含简历、求职者联系方式或校内明文身份信息;
- 任务重试使用相同幂等键,不重复生成业务记录;
- Raw 文件只追加,水位仅在任务完整成功后提交。
## 6. 上线验收
每个来源必须提供:
1. 授权编号、授权范围、有效期、允许字段、允许用途和删除要求;
2. robots.txt 与站点条款快照;
3. 100 条脱敏样本和目标字段映射;
4. 正常、空结果、失效岗位、限流、超时、结构变化和重复数据测试;
5. 请求速率与业务方确认记录;
6. 解析器历史快照回放;
7. Schema、完整性、唯一性、时效和敏感字段检查;
8. 连接器版本、镜像摘要、责任人、告警和回滚版本。
只有以上证据齐全,来源注册中心才能把连接器从 `disabled` 提升到 `approved`,调度器才允许创建公网任务。