单机轻量任务用 schedule,但需「不丢任务」「跨天运行」「失败重试」时必须用 apscheduler;后者支持持久化、自动续跑、并发控制与可靠触发。

用 schedule 还是 APScheduler?别选错启动方式
直接上结论:单机轻量任务用 schedule 足够,但只要涉及「不丢任务」「跨天持续运行」「失败重试」,必须换 APScheduler。前者只是 while 循环+sleep,进程一挂就停;后者自带 jobstore 持久化(比如存到 SQLite 或 Redis),重启后能续跑。
常见错误是拿 schedule 去跑每日 9:15 的开盘抓取——某次网络超时导致主循环卡住,后面所有任务全漏。而 APScheduler 的 BackgroundScheduler 配合 SQLAlchemyJobStore 可以把下次执行时间记进数据库,哪怕 Python 进程崩了,重启后自动补触发。
- 用
APScheduler时,trigger='interval'适合秒级/分钟级行情(如每 30 秒拉一次 tick);trigger='cron'适合固定时刻(如每天 15:00 存日线) - 务必设置
coalesce=True和max_instances=1,防止网络卡顿导致同一任务堆积并发执行 - 不要在 scheduler 启动后直接写
while True: time.sleep(3600),改用block=True或配合signal.pause()
requests 抓接口 vs akshare 封装库:数据源稳定性怎么保?
行情接口极不稳定:交易所限流、字段突变、HTTPS 证书更新、User-Agent 黑名单——纯靠 requests 写死 URL 和解析逻辑,一周内大概率报错。推荐分层处理:
- 优先用
akshare(pip install akshare),它已内置多套 fallback 机制,比如akshare.stock_zh_a_spot_em()会自动切腾讯/东财/新浪多个源,字段名也做了统一映射 - 若需定制字段(如 Level2 十档盘口),再自己封装
requests,但必须加三层防护:1)session复用 + 全局 timeout(timeout=(3, 7));2)Retry策略(urllib3.Retry配置 total=3, backoff_factor=1);3)每次请求前检查响应状态码和关键字段是否存在(比如if 'data' not in res.json()就跳过解析) - 避免用浏览器 User-Agent,换成模拟券商 APP 的 header(如
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)'),部分接口对移动端更宽容
写入 InfluxDB 2.x 时,tag 和 field 别混,否则查不出来
时序数据库不是关系库,measurement 相当于表名,tag 是索引字段(必须字符串,且值不能空),field 才存数值(支持 int/float/bool/string)。爬下来的数据如果把 symbol 当 field 写进去,后续按股票代码查就是全表扫——性能直接崩。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
正确姿势是:把高频过滤条件(如 symbol、exchange)全设为 tag,把行情值(price、volume、bid_price_1)设为 field。InfluxDB 的查询语法里,WHERE 后只能跟 tag,不能查 field。
- Python 写入用
influxdb_client(pip install influxdb-client),别用老的influxdb库,v2.x 不兼容 - 批量写入必须用
WriteApi.write()的record参数传Point对象列表,单点写入(循环调write)吞吐量不到 1/10 - 注意时间戳精度:InfluxDB 默认纳秒,但行情数据毫秒就够了,构造
Point时显式调.time(timestamp_ms, WritePrecision.MS),否则可能被截断或错位
本地测试跑通 ≠ 上生产,Linux 守护进程这三步绕不开
在笔记本上用 python main.py 跑 10 分钟没问题,扔到服务器后台就断连——根本原因是缺少进程管理。systemd 不是可选项,是必选项。
- 写
/etc/systemd/system/stock-crawler.service,关键项:Restart=always(崩溃自动拉起)、RestartSec=10(别秒启,留出 DB 连接恢复时间)、Environment="PYTHONPATH=/opt/crawler"(避免模块找不到) - 日志必须重定向:在 service 文件里加
StandardOutput=journal和StandardError=journal,然后用journalctl -u stock-crawler -f实时看,别写到本地文件再手动轮转 - 数据库连接池要显式关闭:APScheduler 的
shutdown()不会自动关掉 InfluxDB 的client.close(),得在signal.signal(signal.SIGTERM, ...)里手动清理,否则 systemd restart 时旧连接堆积导致端口耗尽
真正麻烦的从来不是第一次写入库,而是三个月后某个凌晨发现某只股票数据连续缺了 47 分钟——这时候你得翻 journal 日志、查 jobstore 表里 last_run_time、比对 InfluxDB 的写入延迟监控,才能定位是网络抖动触发了重试上限,还是 tag 值里混进了非法字符(比如 symbol 里有空格)导致整批写入静默失败。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










