Rockyzsu/stock / 报错排查
为什么这份代码 import 就会崩:四类失败与逐条定位
这个仓库的报错有一个特点:很多问题发生在「运行之前」。也就是说你还没开始做任何事,只是 import 一下就失败了。这类失败对新手最不友好——因为它看起来像是「环境没装好」,实际上可能是代码本身引用了不存在的东西。
本站用 AST 对 100 个已下载的源文件做了导入期审计,把失败分成四类:①导入了不存在的符号(如 from configure.settings import get_engine,而该模块只导出 4 个符号);②Python 2 残留(import Queue、import cookielib、email.Utils);③新版本移除的 API(np.str、collections.Iterable、to_sql(flavor=));④配置键与文件缺失。每一类下面都给出了具体文件与行号。
导入期失败
类型一:导入了不存在的符号怎么排查(最容易被误判为「依赖没装」)
| 文件 | 源码位置 | 问题写法 | 为什么会失败 | 修复方向 |
|---|---|---|---|---|
select_stock.py | 第 19 行 | from configure.settings import get_engine | configure/settings.py 只导出 get_config_data / config_dict / DBSelector / get_tushare_pro 和变量 config;get_engine 只是 DBSelector 的方法 | 改成 DBSelector().get_engine('db_stock') |
pledged_validation.py | 第 5 行 | from configure.settings import get_engine | 同上 | 同上 |
recordMyChoice.py | 第 14、16 行 | get_mysql_conn、LLogger | 两个符号在 settings.py 中都不存在(get_mysql_conn 是方法、LLogger 类根本没有) | 用 DBSelector().get_mysql_conn();日志类需自己实现或改用 loguru |
transfer_data_es.py | 第 6 行 | get_mysql_conn | 同上 | 同上 |
stockInfo.py | 第 16 行 | llogger(小写) | 该符号不存在 | 改用 loguru / logging |
k_line.py | 第 10 行 | MYSQL_HOST, MYSQL_PORT, MYSQL_USER, MYSQL_PASSWORD, REDIS_HOST | 这五个常量在 settings.py 中不存在(配置是通过 DBSelector 按档案读取的) | 改成从 config.json 读取或调用 DBSelector |
StockAnalyze.py | 第 234 行 | 直接调用 get_engine('db_stock') | 第 7 行只导入了 DBSelector,函数内调用的是未导入的名字 | 改成 DBSelector().get_engine('db_stock') |
trader/auto_trader.py | 第 11 行 | from config import PROGRAM_PATH, MONGO_PORT, MONGO_HOST | 仓库中没有 config.py,且 .gitignore 明确忽略它 | 自建 config.py 并定义三个常量 |
datahub/industry_info/*.py(3 个) | 各文件头部 | from data_dump import DataDump、from cookies_generator import gen_cookies | 这两个模块在整个仓库中都不存在 | 需自备或改写(属未完成迁移) |
datahub/store_news.py | 头部 | import setting | 仓库里没有这个模块(实际是 configure/settings.py) | 改成 from configure.settings import ... |
monitor/statistices.py | 第 1 行 | import alert | 仓库里没有 alert.py(同目录有 alert_me.py) | 改成 import 正确的文件名 |
这一类的共同特征:报错信息是 ImportError 或 ModuleNotFoundError,容易让人以为是「依赖没装」。但实际上这些名字既不是第三方包、也不是漏装的依赖——它们是代码引用错了。判断方法很简单:pip list 里找不到、而且名字看起来像项目内部的模块名。
Python 2 残留
类型二:Python 2 残留怎么识别(用 Python 3 一定失败)
| 文件 | 问题写法 | 为什么是 Python 2 | 修复方向 |
|---|---|---|---|
select_stock.py | import Queue | Python 3 的模块名是 queue(全小写),Queue 是 Python 2 的写法 | 改 from queue import Queue |
select_stock.py | 使用 unicode(i) | unicode 是 Python 2 的内建类型,Python 3 中不存在 | 改用 str(i) |
snowball.py、strategy_verify.py | import cookielib | Python 3 中移到 http.cookiejar | 改 import http.cookiejar as cookielib 或改写请求方式 |
relationship_case.py | from pylab import ... | pylab 是早期 matplotlib 的兼容命名空间,Python 2 时代常见 | 改用 matplotlib.pyplot |
utils/push_msn.py、jubi.py | from email import Utils | email.Utils 在 Python 3.3 起已移除(改为 email.utils) | 改用 from email.utils import formatdate |
utils/push_msn.py、jubi.py、real_time_big_deal.py | 使用 long() | long 是 Python 2 的内建类型 | 改用 int() |
jubi.py | 文件头注释:「## python2代码,网站已经停止更新」 | 作者已明确标注该脚本为 Python 2 且站点停更 | 整体弃用或重写 |
这类文件的数量不多,但提示了一个重要事实:这个仓库横跨了 Python 2 到 Python 3 的迁移期,不同文件写于不同年代。所以「用哪个 Python 版本」这个问题没有统一答案——只能逐个文件看。上面的七个文件用 Python 3 跑一定失败。
现代版本陷阱
类型三:新版本移除的 API 怎么核对版本号
| 写法 | 出现在 | 从哪个版本开始失效 | 替代写法 | 发生时机 |
|---|---|---|---|---|
np.str | 10 个文件:k_line.py、monitor/realtime_monitor_ts.py、new_stock_break.py、real_time_big_deal.py、select_stock.py、stock_check.py、utils/delivery_order.py(6 处)、utils/push_msn.py、datahub/repurchase.py | NumPy 2.0 移除 | 改用 str 或 np.dtype('U') | 运行到该行时 AttributeError |
from collections import Iterable | futu/basic_usage.py、futu/util.py | Python 3.10 起需从 collections.abc 导入 | from collections.abc import Iterable | import 阶段即失败 |
df.to_sql(..., flavor='sqlite') | store_data.py | pandas 1.0 移除 flavor | 去掉该参数,改用 sqlite3 连接直接传入 | 运行到该行时 TypeError |
es.index(..., doc_type='doc', ...) | stockInfo.py | elasticsearch-py 8.x 移除 doc_type | 去掉 doc_type(新版不再需要) | 运行到该行时参数错误 |
mpl_finance | k-line/ 3 个文件与 plot_line.py | 上游已弃用并改名为 mplfinance | 改用 mplfinance(API 有变化) | import 阶段可能失败 |
talib | k-line/recognize_form.py、k-line/search_target.py、plot_line.py | 不是版本问题,而是需要本地 C 库 | 先装 TA-Lib 的 C 库再 pip 装包装层 | import 阶段失败 |
execjs | datahub/jsl_login.py、datahub/ttjj_new_stock.py | 需要 Node.js 运行时 | 本机安装 Node | 调用时失败 |
本站在这里给出「从哪个版本开始失效」时非常克制:上表中 NumPy 2.0、Python 3.10、pandas 1.0、elasticsearch 8.x 都是明确的版本号事实(可在各自官方变更日志中核对)。但本站不对「Tushare 某个接口几号下线」这类问题做断言——那需要逐条查官方公告,无法从源码推出。
配置与文件缺失
类型四:配置键与文件缺失(报错信息里会带文件名)
| 依赖 | 缺失内容 | 报错时机 | 影响范围 | 修复方向 |
|---|---|---|---|---|
configure/config.json | 该文件被 .gitignore 排除,仓库里只有 sample_config.json | import configure.settings 时立即 FileNotFoundError | 几乎所有脚本 | 复制样例并填写 |
jsl_monitor 的 5 个键 | ZZ_PERCENT、ZG_PERCENT、REMAIN_SIZE、ACCESS_INTERVAL_REALTIME、REDIS_KEY | import monitor.jsl_monitor 时 KeyError | 可转债监控全链路 | 按代码读取的键补齐配置 |
redis.uc 子对象 | 样例只给了 redis.qq,而监控脚本读 redis.uc | 同上 KeyError | 监控推送 | 补 uc 子对象或改代码读取路径 |
configure/web_headers.json | 整个文件不存在(configure/ 下只有 3 个文件) | read_web_headers_cookies() 调用时 FileNotFoundError | monitor/realtime_kzz_price.py、datahub/ttjj_new_stock.py | 自己导出请求头与 cookie 写入该文件 |
datahub/validate_key.py 的字段 | 四个字段全为空字符串(作者注释写「找群主要」) | 验证码识别请求失败 | 宁稳网数据链路 | 需自行准备 OCR 服务 |
bases.csv | 被 6 个脚本引用,但在 .gitignore 里 | 读取时 FileNotFoundError | select_stock.py、k_line.py、stock_check.py 等 | 由 select_stock.py 的本地分支生成 |
config.py 与 user.json | 被 .gitignore 排除 | import 与 prepare() 时失败 | 交易链路 | 自行创建(凭证文件切勿提交) |
log/ 目录 | 仓库中不存在(.gitignore 里有 log/jsl_monitor) | loguru 写日志时路径错误 | 监控脚本 | 先手工创建目录 |
这一类的特征是「报错信息里出现文件名」。看到 FileNotFoundError: config.json 或 KeyError: 'ZZ_PERCENT' 时,不要先怀疑环境——先按本表确认该文件或该键是否本来就该由你提供。
排查顺序
六步排查方法:先分类,再定位
报错排查的推荐顺序
- 先判断失败发生在哪个阶段:是
import就报错,还是运行到某一行才报错。预期输出:明确是导入期问题还是运行期问题。前者看本页类型一、二,后者看类型三。 - 如果是导入期且报
ImportError,先在源码里搜索这个名字是「项目内部符号」还是「第三方包」。预期输出:区分「代码引用错了」与「依赖没装」。 - 如果是第三方包,确认它是否在
requirements.txt里。不在的话就属于要自己补的约 24 个包之一。预期输出:拿到一份需要补装的清单。 - 如果报的是
KeyError/FileNotFoundError,打开报错里提到的文件路径,对照本页类型四表判断它是「样例里有」还是「样例里也没有」。预期输出:知道该自己建什么。 - 如果是运行到某行才报
AttributeError(如np.str),先确认你装的相关库版本,再决定是改代码还是降版本。预期输出:明确的版本与改动方案。 - 最后再考虑业务逻辑问题。预期输出:此时脚本至少已经能进入主流程。
FAQ
关于 Rockyzsu/stock 的常见问题
为什么这么多模块导入就失败?
get_engine 从模块级函数改成 DBSelector 的方法),但调用方没有全部同步更新;其二,仓库横跨 Python 2 到 Python 3 的迁移期,早期的文件保留了 Python 2 的模块名与内建函数。本站通过 AST 审计定位到至少 8 个模块存在导入期问题,完整清单见本页类型一、二表。该用哪个 Python 版本?
select_stock.py 用了 Python 2 的 Queue,futu/ 用了 Python 3.10 起才失效的 collections.Iterable——也就是说没有一个版本能同时跑通全部文件。实际做法是逐文件判断:以 f-string 语法推断最低需要 3.6;如果要用 futu/,就要避免 3.10 及以上;如果要跑 select_stock.py,就要先把 Queue 改掉。报错说是 ModuleNotFoundError,装包就能解决吗?
talib、backtrader),那是依赖没装;②报错的名字像是项目内部模块(如 data_dump、cookies_generator、setting、alert),那是代码引用了不存在的模块——这些在 PyPI 上根本不存在,装不到。datahub/industry_info/ 下三个脚本就是后者。np.str 报错怎么修?
np.str 改成 str(大多数场景够用);②如果要保留 numpy 语义,改成 np.dtype('U') 相关的写法;③降级到 NumPy 1.x。需要改的文件有 10 个,其中 utils/delivery_order.py 出现 6 次最多。注意本页只列位置,不保证改完就能跑通所有业务逻辑。我怎么知道一个警告是「代码问题」还是「环境问题」?
pip index versions 查一下——查不到的就是项目内部符号,属于代码问题;能查到并且是知名项目的,才可能是环境问题。这个方法能省下大量「反复重装依赖」的时间。这些报错会不会因为作者修了就不存在了?
9478dee528cc(2026-04-17)。如果之后有新提交,请以新提交的源码为准重新核对。本站不在页面里写「当前」「目前」这类无法验证的时间词。