Skip to content
📌知识点小结
  • 报错不是失败,而是程序在告诉你“哪一行、出了什么问题”,要学会读它。
  • 读报错顺序:先看最后一行(错误类型+信息),再向上看是哪个文件、哪一行触发。
  • 常见错误:SyntaxError 语法、NameError 名字未定义、TypeError 类型不对、ValueError 值非法、IndentationError 缩进。
  • 复制关键报错去搜索/查文档,往往能快速定位。
  • 安全复现里报错是常态,关键是把报错转化为下一步排查方向。
✅自测一下

0.32 怎么看懂报错信息 ​

第〇篇【零基础预科】免费。新手最怕一屏红字,其实报错是最好的老师——它把问题位置和原因都写给你了。

一、报错在说什么 ​

一段典型报错:

Traceback (most recent call last):
  File "detect.py", line 10, in <module>
    print(urll)
NameError: name 'urll' is not defined

读法分两部分:

  1. 上面 Traceback:调用经过的文件和行号(问题在哪);
  2. 最后一行:错误类型 + 说明(出了什么事)——这是首先要看的。

你可能会问:一整屏红字,是不是说明问题很严重、电脑要坏? 不是。红色只是终端标记错误的惯例,真正有用的是文字内容;大多数报错只是"这行没写对",改一个字符就好。另外要分清 Warning(警告) 和 Error(错误):警告是"这么写不太好、以后可能出问题",程序往往还能继续跑;错误才是"走不下去了"。看到警告也别完全无视,它常常是在提前提醒隐患。

再说说 Traceback 为什么有时很长。它其实是一条调用链:你的程序在第 A 处调用了函数 B,B 里又调用了 C,最后在 C 里炸了——Traceback 自上而下把"经过了哪些文件、哪些行"依次列出,最底下才是真正出错的地方。读法是:先看最底下定性(出了什么事),再顺着往上回溯(怎么走到这一步的)。新手常犯的错是盯着最上面第一行看,反而没看到最后一行的结论。

还有个要提醒的细节:报错给的行号是"问题在这被发现",但真正的错误可能在更上面。比如少写一个右括号,解释器往往到下一行才察觉,报的行号比实际位置靠后;又如 NameError 说某变量没定义,根因常常是你在前面忘了赋值、或赋值那行被放进了没执行到的分支里。所以定位到那行、若看着没问题,就往上翻一翻,想想这个名字本该在哪里被定义。

二、常见错误类型速查 ​

错误常见原因例子
SyntaxError语法写错(少括号/冒号/引号)if x 没冒号
IndentationError缩进错误混用空格/Tab、层级乱
NameError名字未定义/拼错print(urll)
TypeError类型不支持该操作"10" + 5
ValueError值合法类型但内容非法int("abc")
IndexError / KeyError列表下标越界 / 字典键不存在arr[9]、d["x"]
FileNotFoundError文件路径不对/文件不存在打开错路径
ModuleNotFoundError库没装/模块名错未 pip install

把最常见的几个,用"错在哪、怎么改"过一遍:

python
# NameError:名字拼错 / 没定义
pront("hi")            # 应为 print
count = Count + 1      # 大小写不一致,前面定义的是 count
python
# IndentationError:缩进没对齐(Python 靠缩进区分代码块)
if ok:
    print("yes")
      print("again")   # 这行多缩进了一级,要和上一行对齐
python
# KeyError:字典里没有这个键
user = {"name": "eason"}
print(user["age"])     # 没有 age;可先判断,或用 user.get("age")

都是非常小的疏忽,但新手容易被"错误类型"这个名字唬住;对照表格一看,往往一眼就明白。

三、排查四步法 ​

  1. 看类型和最后一行:先定性;
  2. 找行号:回到那一行仔细看;
  3. 最小复现 + print:把相关变量打印出来看实际值;
  4. 复制关键信息检索:用"错误类型 + 关键信息"查文档/搜索,往往是常见坑。

第 3 步具体怎么做?假设报错是 TypeError: can only concatenate str (not "int") to str、指向某一行拼接,你就在那行之前插入打印,看看变量到底是什么:

python
print("url =", url, "| 类型 =", type(url))

一跑就知道,比如你以为是文字的 url 其实是数字,后面拼接自然失败。所谓"最小复现",是把出问题的那段逻辑单独抽出来、用最少的代码让它再错一次——排除掉无关部分后,原因往往立刻清楚。新手和老手的差距,很多时候就在于会不会主动 print 出"程序眼里的真实值",而不是凭"我以为"反复猜。

还有两个通用小技巧。一是二分法定位:不确定哪段出问题时,先注释掉一半、运行,看错误还在不在,像查字典一样每次排除一半,几次就能锁定范围。二是要意识到报错不止出现在终端:浏览器按 F12 的 Console、服务器的日志文件里也有报错,但"先看结论、再找位置"的读法完全通用,会看一种,其他的都不慌。

四、安全复现中的报错 ​

  • 连不上目标:ConnectionRefusedError / 超时 → 靶场没起、端口不对、IP 错;
  • 模块缺失:ModuleNotFoundError: requests → pip install requests;
  • 权限不足:Permission denied → 加 sudo / 检查文件权限;
  • 响应不是预期 JSON:JSONDecodeError → 你可能拿到的是一张报错 HTML 页,先 print(resp.text[:200]) 看实际返回;
  • 状态码 401/403:不是连不上,而是"需要认证 / 没权限",排查方向和网络问题完全不同;404 则是路径或接口写错。
  • 漏洞没复现成功时,报错和响应内容就是线索,对照原理逐步定位,而不是反复重跑同一条命令。

这里有个特别实用的区分:同样是"连不上",Connection refused(连接被拒绝) 和**timeout(超时)** 指向完全不同的原因。前者像"电话拨通了但对方说没这个分机"——通常是目标主机在线、但那个端口没服务在听(靶场没起、端口写错);后者像"电话一直没人接"——可能是 IP 不通、防火墙把包丢了、或路由不可达。看到报错先做这一步区分,排查方向就不会错。

搜索报错也有讲究:复制"错误类型 + 稳定的关键信息"(如 NameError: name 'xxx' is not defined),去掉你项目特有的文件路径和用户名;优先看官方文档、Stack Overflow 上被采纳的回答,并留意回答的时间(老版本的解法可能已失效)。别把几十行 Traceback 整段丢进搜索框,既搜不准、也容易暴露自己的环境信息。

最后强调一条排查纪律:每次只改一处、再跑一次。同时改好几样,就算碰巧成功,你也不知道是哪一处起的作用,下次还是不会;而原封不动地反复重跑同一条命令,结果不会自己变好。把"报错 → 假设一个原因 → 只验证这一处 → 记录结果"变成习惯,排查就从瞎试变成了有章法的推理。

顺带一提,报错不一定非要"崩给用户看":程序里可以用 try/except 主动接住异常、换个方式处理(比如目标连不上就跳过并记录,而不是整个脚本停掉)。你在 detect.py 里会看到这类写法,等学到异常处理再细究,现在知道"异常是可以被程序自己接住的"即可。

五、心态 ​

  • 报错说明程序在正常反馈,不是你"不行";
  • 资深工程师不是不犯错,而是能快速读懂报错、定位问题;
  • 每次解决一个报错,把原因记一笔,同类问题会越来越快。

"记一笔"可以非常简单:一个文本文件,每次写下报错类型 → 真正原因 → 怎么改的,哪怕只写一行。下次再遇到,搜自己的记录比重新全网找快得多;积累下来,你会发现自己常踩的坑就那么十几类,排查速度肉眼可见地变快。这也是在把"每次都从零开始的慌",变成"有台账可循的稳"。

报错多为英文,其实高频词就几个,认识它们就够用:not defined(没定义)、expected(本应出现,如 expected ':')、invalid(非法)、denied(被拒绝)、not found(没找到)、refused(拒绝连接)、timed out(超时)。配合错误类型,连蒙带猜基本能懂个八九分,并不需要英语多好。也可以直接把报错发给 AI 或朋友,但建议你自己先读一遍、说清你当时想做什么——这个"先自己理解"的动作,正是能力长在你身上的关键(怎么高效提问,0.33 专门讲)。

六、本篇小结 ​

  • 先看最后一行(类型+信息),再向上找文件行号。
  • 常见:Syntax/Indentation/Name/Type/Value/Index/Key/FileNotFound/ModuleNotFound。
  • 排查:定性→定位行→print 检查→检索关键信息。
  • 把报错当线索,逐步对照原理排查。

下一篇 0.33 讲怎么高效提问,让别人愿意且能快速帮到你。