Files
tg_crawl/README.md
2026-03-05 23:55:18 +08:00

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