Files
tg_crawl/README.md

211 lines
5.7 KiB
Markdown
Raw Normal View History

2026-02-26 20:00:06 +08:00
# jobs_robots
Telegram 招聘数据采集与清洗项目,当前主流程为:
2026-02-26 20:00:06 +08:00
1. 抓取原始消息到本地 MySQL
2. 清洗为结构化岗位数据
3. 每日定时增量执行
4. 同步本地 MySQL 到云端 MySQL
2026-02-26 20:00:06 +08:00
## 1. 项目结构
2026-02-26 20:00:06 +08:00
- `main.py`: Telegram 增量爬取,写入 `messages`,维护 `sync_state`
- `clean_to_structured.py`: 按来源规则清洗,写入 `structured_jobs`,维护 `clean_state`
- `import_excel_jobs.py`: 读取 `sheets/` Excel导入结构化数据实习数据落 `internship_jobs_raw`
- `sync_to_cloud_mysql.py`: 本地 MySQL -> 云端 MySQL 增量同步
- `run_daily_incremental.sh`: 每日调度入口(滚动窗口、抓取、清洗、云同步)
- `config.json`: 运行配置(本地使用)
- `config.example.json`: 配置模板
2026-02-26 20:00:06 +08:00
## 2. 环境要求
2026-02-26 20:00:06 +08:00
- Python `>=3.13`
- MySQL 8.x本地
- MySQL 8.x云端可选
- 已完成 Telethon 登录(项目目录下会生成 `scraper.session`
2026-02-26 20:00:06 +08:00
依赖安装:
2026-02-26 20:00:06 +08:00
```bash
uv sync
```
2026-02-26 20:00:06 +08:00
## 3. 配置说明
2026-02-26 20:00:06 +08:00
先复制模板并修改:
2026-02-26 20:00:06 +08:00
```bash
cp config.example.json config.json
```
2026-02-26 20:00:06 +08:00
关键字段:
2026-02-26 20:00:06 +08:00
- `sources`: 要抓取的 Telegram 来源列表
- `time_window`: 抓取时间窗口
- `daily_window_days`: 每日滚动窗口天数(默认 `2`
- `backfill`: 回补配置
- `throttle`: 限频配置,降低封号风险
- `mysql`: 本地 MySQL 连接
- `mysql_cloud`: 云端 MySQL 连接(用于同步)
2026-02-26 20:00:06 +08:00
## 4. 运行方式
2026-02-26 20:00:06 +08:00
### 4.1 手动执行
2026-02-26 20:00:06 +08:00
```bash
uv run main.py
uv run clean_to_structured.py
uv run sync_to_cloud_mysql.py
```
2026-02-26 20:00:06 +08:00
如果在 cron/非交互环境,建议用 venv Python
2026-02-26 20:00:06 +08:00
```bash
.venv/bin/python main.py
.venv/bin/python clean_to_structured.py
.venv/bin/python sync_to_cloud_mysql.py
```
2026-02-26 20:00:06 +08:00
### 4.2 Excel 导入
2026-02-26 20:00:06 +08:00
默认读取 `sheets/` 下文件:
2026-02-26 20:00:06 +08:00
```bash
uv run import_excel_jobs.py
```
2026-02-26 20:00:06 +08:00
指定文件/工作表:
2026-02-26 20:00:06 +08:00
```bash
uv run import_excel_jobs.py --file /path/to/jobs.xlsx --sheet Sheet1 --source @excel_import
```
2026-02-26 20:00:06 +08:00
导入规则:
2026-02-26 20:00:06 +08:00
- 普通岗位:清洗后写入 `structured_jobs`
- 实习岗位:写入 `internship_jobs_raw`,不进入结构化主表
2026-02-26 20:00:06 +08:00
### 4.3 每日定时(推荐)
2026-02-26 20:00:06 +08:00
调度脚本:
2026-02-26 20:00:06 +08:00
- `/home/liam/code/python/jobs_robots/run_daily_incremental.sh`
2026-02-26 20:00:06 +08:00
示例 crontab每天 01:10
2026-02-26 20:00:06 +08:00
```cron
10 1 * * * /home/liam/code/python/jobs_robots/run_daily_incremental.sh
```
2026-02-26 20:00:06 +08:00
脚本执行顺序:
2026-02-26 20:00:06 +08:00
1. 自动更新 `config.json``time_window.start/end`(按 `daily_window_days`
2. 运行 `main.py` 增量抓取
3. 运行 `clean_to_structured.py` 增量清洗
4.`mysql_cloud` 已配置,运行 `sync_to_cloud_mysql.py` 同步云端
2026-02-26 20:00:06 +08:00
## 5. 增量与回补策略
2026-02-26 20:00:06 +08:00
### 5.1 抓取增量
2026-02-26 20:00:06 +08:00
- 状态表:`sync_state`
- 游标字段:`last_message_id`
- 粒度:每个 source 独立
2026-02-26 20:00:06 +08:00
### 5.2 清洗增量
2026-02-26 20:00:06 +08:00
- 状态表:`clean_state`
- 游标字段:`last_message_row_id`(对应 `messages.id`
- 规则:仅处理 `messages.id > checkpoint`
2026-02-26 20:00:06 +08:00
### 5.3 回补Backfill
2026-02-26 20:00:06 +08:00
`config.json` 设置:
2026-02-26 20:00:06 +08:00
- `backfill.enabled = true`
- `backfill.start / backfill.end`
- `backfill.sources`
- `backfill.ignore_sync_state`(回补时是否忽略抓取游标)
2026-02-26 20:00:06 +08:00
回补结束后建议关闭 `backfill.enabled`,恢复日常增量。
2026-02-26 20:00:06 +08:00
## 6. 本地到云端同步
2026-02-26 20:00:06 +08:00
脚本:`sync_to_cloud_mysql.py`
2026-02-26 20:00:06 +08:00
同步规则:
2026-02-26 20:00:06 +08:00
- `messages`: 按本地 `id` 增量,云端按 `(source, message_id)` upsert
- `structured_jobs`: 按本地 `id` 增量 + `cleaned_at` 补偿更新
- `sync_state` / `clean_state`: 小表全量 upsert
- `internship_jobs_raw`: 存在则按 `id` 增量 upsert
2026-02-26 20:00:06 +08:00
状态表(云端):
2026-02-26 20:00:06 +08:00
- `cloud_sync_state`
2026-02-26 20:00:06 +08:00
注意:
2026-02-26 20:00:06 +08:00
- 同步脚本会自动在云端补齐缺失目标表(从本地表结构复制 DDL
- `mysql_cloud` 未配置时,日常脚本会跳过云同步
2026-02-26 20:00:06 +08:00
## 7. 数据库表与字段含义
2026-02-26 20:00:06 +08:00
### 7.1 原始层
2026-02-26 20:00:06 +08:00
- `messages`
- 原始消息正文、媒体补充文本、来源、消息时间
- 唯一键:`(source, message_id)`
- `sync_state`
- 每个 source 的抓取游标
2026-02-26 20:00:06 +08:00
### 7.2 清洗层
2026-02-26 20:00:06 +08:00
- `structured_jobs`
- 清洗后结构化岗位数据
- 唯一键:`(source, message_id)`
- 关键字段:
- `source`, `source_channel`
- `company_name`, `position_name`
- `work_mode``remote|onsite|hybrid|unknown`
- `job_nature``full_time|part_time|contract|intern|freelance|unknown`
- `job_location_text`, `job_location_tags_json`(无地点为 `NULL`
- `apply_email`, `apply_telegram`, `job_source_url`
- `salary_raw`, `salary_currency`, `salary_min`, `salary_max`, `salary_period`
- `body_text`, `raw_content`, `cleaned_at`
- `clean_state`
- 清洗检查点
- `internship_jobs_raw`
- Excel 导入时保留的实习原始数据
2026-02-26 20:00:06 +08:00
## 8. 日志
2026-02-26 20:00:06 +08:00
- `logs/app.log`: 抓取日志
- `logs/clean_to_structured.log`: 清洗日志
- `logs/sync_to_cloud_mysql.log`: 云同步日志
- `logs/daily_job.log`: 每日调度总日志
2026-02-26 20:00:06 +08:00
## 9. 常见问题
2026-02-26 20:00:06 +08:00
1. `uv: command not found`cron
- 使用 `.venv/bin/python` 运行,已在 `run_daily_incremental.sh` 中处理。
2026-02-26 20:00:06 +08:00
2. `Table 'jobs.messages' doesn't exist`(云同步)
- 云端目标库为空。新版同步脚本会自动建表后再同步。
2026-02-26 20:00:06 +08:00
3. `Public Key Retrieval is not allowed`DBeaver 连 MySQL
- 连接参数添加 `allowPublicKeyRetrieval=true&useSSL=false`(排障用)。
2026-02-26 20:00:06 +08:00
4. `ERROR 1410 You are not allowed to create a user with GRANT`
-`CREATE USER`,再 `GRANT`,不要用旧式 `GRANT ... IDENTIFIED BY ...`
2026-02-26 20:00:06 +08:00
5. 清洗无新增
- 检查 `messages` 是否有新数据。
- 检查 `clean_state.last_message_row_id` 是否已到最新。
2026-02-26 20:00:06 +08:00
## 10. 协作规范建议
2026-02-26 20:00:06 +08:00
- 新增来源规则时,优先增加 source 专用 parser避免影响已有来源。
- 结构字段变更前,先确认 `structured_jobs` 迁移策略和历史兼容。
- 定时任务统一走 `run_daily_incremental.sh`,避免多个入口重复执行。