70fce8ebab29e296f2d7c672c0d24baaf0b80cec
jobs_robots
Telegram 招聘数据采集与清洗项目,当前主流程为:
- 抓取原始消息到本地 MySQL
- 清洗为结构化岗位数据
- 每日定时增量执行
- 同步本地 MySQL 到云端 MySQL
1. 项目结构
main.py: Telegram 增量爬取,写入messages,维护sync_stateclean_to_structured.py: 按来源规则清洗,写入structured_jobs,维护clean_stateimport_excel_jobs.py: 读取sheets/Excel,导入结构化数据,实习数据落internship_jobs_rawsync_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)
依赖安装:
uv sync
3. 配置说明
先复制模板并修改:
cp config.example.json config.json
关键字段:
sources: 要抓取的 Telegram 来源列表time_window: 抓取时间窗口daily_window_days: 每日滚动窗口天数(默认2)backfill: 回补配置throttle: 限频配置,降低封号风险mysql: 本地 MySQL 连接mysql_cloud: 云端 MySQL 连接(用于同步)
4. 运行方式
4.1 手动执行
uv run main.py
uv run clean_to_structured.py
uv run sync_to_cloud_mysql.py
如果在 cron/非交互环境,建议用 venv Python:
.venv/bin/python main.py
.venv/bin/python clean_to_structured.py
.venv/bin/python sync_to_cloud_mysql.py
4.2 Excel 导入
默认读取 sheets/ 下文件:
uv run import_excel_jobs.py
指定文件/工作表:
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):
10 1 * * * /home/liam/code/python/jobs_robots/run_daily_incremental.sh
脚本执行顺序:
- 自动更新
config.json的time_window.start/end(按daily_window_days) - 运行
main.py增量抓取 - 运行
clean_to_structured.py增量清洗 - 若
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 = truebackfill.start / backfill.endbackfill.sourcesbackfill.ignore_sync_state(回补时是否忽略抓取游标)
回补结束后建议关闭 backfill.enabled,恢复日常增量。
6. 本地到云端同步
脚本:sync_to_cloud_mysql.py
同步规则:
messages: 按本地id增量,云端按(source, message_id)upsertstructured_jobs: 按本地id增量 +cleaned_at补偿更新sync_state/clean_state: 小表全量 upsertinternship_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_channelcompany_name,position_namework_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_urlsalary_raw,salary_currency,salary_min,salary_max,salary_periodbody_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. 常见问题
uv: command not found(cron)
- 使用
.venv/bin/python运行,已在run_daily_incremental.sh中处理。
Table 'jobs.messages' doesn't exist(云同步)
- 云端目标库为空。新版同步脚本会自动建表后再同步。
Public Key Retrieval is not allowed(DBeaver 连 MySQL)
- 连接参数添加
allowPublicKeyRetrieval=true&useSSL=false(排障用)。
ERROR 1410 You are not allowed to create a user with GRANT
- 先
CREATE USER,再GRANT,不要用旧式GRANT ... IDENTIFIED BY ...。
- 清洗无新增
- 检查
messages是否有新数据。 - 检查
clean_state.last_message_row_id是否已到最新。
10. 协作规范建议
- 新增来源规则时,优先增加 source 专用 parser,避免影响已有来源。
- 结构字段变更前,先确认
structured_jobs迁移策略和历史兼容。 - 定时任务统一走
run_daily_incremental.sh,避免多个入口重复执行。
Description
Languages
Python
97.7%
Shell
2.3%