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

依赖安装:

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

脚本执行顺序:

  1. 自动更新 config.jsontime_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_moderemote|onsite|hybrid|unknown
      • job_naturefull_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 foundcron
  • 使用 .venv/bin/python 运行,已在 run_daily_incremental.sh 中处理。
  1. Table 'jobs.messages' doesn't exist(云同步)
  • 云端目标库为空。新版同步脚本会自动建表后再同步。
  1. Public Key Retrieval is not allowedDBeaver 连 MySQL
  • 连接参数添加 allowPublicKeyRetrieval=true&useSSL=false(排障用)。
  1. ERROR 1410 You are not allowed to create a user with GRANT
  • CREATE USER,再 GRANT,不要用旧式 GRANT ... IDENTIFIED BY ...
  1. 清洗无新增
  • 检查 messages 是否有新数据。
  • 检查 clean_state.last_message_row_id 是否已到最新。

10. 协作规范建议

  • 新增来源规则时,优先增加 source 专用 parser避免影响已有来源。
  • 结构字段变更前,先确认 structured_jobs 迁移策略和历史兼容。
  • 定时任务统一走 run_daily_incremental.sh,避免多个入口重复执行。
Description
No description provided
Readme 418 KiB
Languages
Python 97.7%
Shell 2.3%