0.28 循环:让程序重复干活
第〇篇【零基础预科】免费。自动化之所以强大,关键就在循环——写一次,重复执行成百上千遍。
上一篇我们让程序"看情况办事",这一篇让它"不知疲倦地重复"。条件判断管的是分叉,循环管的是重复,两者一组合,程序就能处理任意多个目标。
一、for 循环:遍历集合
ports = [22, 80, 443]
for port in ports:
print("检查端口:", port)- 依次从列表取出元素放进
port,每取一个执行一次缩进块; - 循环次数 = 元素个数。
这个 ports = [22, 80, 443] 就是一个装了三个数字的列表。你可以把它看成一张待办清单,for 就是"对着清单上每一条,都做一遍同样的事"。换成别的清单也行:把 ports 换成域名清单、换成漏洞名称清单,循环体照样跑。学会这一个句式,"批量"这件事你就掌握了大半。
range:重复固定次数
for i in range(3):
print("第", i, "次")
# 第 0 次 / 第 1 次 / 第 2 次range(3) 产生 0、1、2,含头不含尾。
为什么需要循环?设想你要检查 100 个端口。不用循环,你得把"检查端口"这段代码手抄 100 遍,端口号从 22 一直写到 121,光复制粘贴就眼花,改一处逻辑还要改 100 遍。用循环,你只写一遍"取出一个端口、检查它",剩下的交给电脑去重复——它一秒钟重复一万遍也不烦、不漏。这就是自动化的本质:把"动作"写一遍,把"重复"交给机器。
port 这个名字是你自己起的变量,每转一圈,它就被赋成列表里的下一个值。第一圈 port 是 22,第二圈是 80,第三圈是 443,列表取完,循环自动结束。你可以把它想成流水线的传送带:每来一个零件(元素),工人(循环体)就处理一个。
你可能会问:
range(3)为什么不包括 3?从 0 开始? 这是初学者最常见的困惑。range(3)给的是0、1、2,一共 3 个数——它表达的是"重复 3 次",而不是"数到 3"。从 0 开始是计算机的习惯(序号常从 0 算起)。你要是想从 1 数到 10,得写range(1, 11):左边含、右边不含,所以终点要多写 1。想每隔两个取一次,还能写range(0, 10, 2)得到0、2、4、6、8。记住"含头不含尾"这四个字就够了。
二、while 循环:条件为真就重复
count = 0
while count < 3:
print("count =", count)
count = count + 1- 每次循环前检查条件,真就执行;
- 必须让条件最终变假,否则会死循环(一直跑不结束);
- 死循环时可按
Ctrl + C中断。
for 和 while 怎么选?很简单:知道要重复几次、要遍历一个已知名单,就用 for;不知道会重复几次、只知道"满足某个条件就继续",就用 while。比如"遍历这 100 个 IP"用 for;"一直重试连接,直到连上为止"用 while——你事先不知道要试几次,只能靠条件 while 还没连上: 来控制。
说个真会发生的事:新手写 while count < 3:,却忘了在循环体里写 count = count + 1。于是 count 永远是 0,条件永远为真,程序像卡住一样疯狂打印。这时终端里按 Ctrl + C 就能强行停掉——这也是 0.12 里讲"终端 Ctrl+C 是中断不是复制"的用武之地。停掉后回到代码,检查循环体里到底有没有"让条件慢慢变假"的那一步,多半就找到了。
三、break 与 continue
for n in range(10):
if n == 5:
break # 到 5 直接结束整个循环
if n % 2 == 0:
continue # 偶数跳过后面,进入下一轮
print(n) # 只打印奇数 1,3| 关键字 | 作用 |
|---|---|
break | 立刻跳出循环 |
continue | 跳过本次、继续下一次 |
这两个词的区别用找东西来类比最清楚:你在一串目标里挨个检测,一旦发现了漏洞,立刻 break——后面不用再测了,收工;如果某个目标连不上、测不了,就 continue——别在它身上耗着,跳过它、测下一个。break 是"这事办成了/不用再转了,整轮停下",continue 是"这一个不算数,赶紧下一个"。
容易混的一点:continue 只是跳过当前这一圈剩下的语句,循环本身还在继续;break 才是把整个循环结束掉。读别人的批量脚本时,看到这俩词就在脑子里过一遍"是停整个、还是跳过这一次",就不会看错流程。
四、安全脚本里的循环
targets = ["http://a.com", "http://b.com", "http://c.com"]
for url in targets:
print("正在检测:", url)
# response = requests.get(url, timeout=5)
# if "特征" in response.text:
# print(url, "可能存在漏洞")这就是"批量检测"的基本骨架:用循环遍历目标,对每个目标做同样的检查。
真实写起来还有两个细节你早晚会撞到。一是别把对方打挂:循环里一秒钟对着某个站发几百个请求,轻则被封 IP,重则影响人家正常业务。所以脚本里常会加一句 time.sleep(0.5),每测一个歇半秒——这不是啰嗦,是基本的分寸。二是要加超时:某个目标连不上,请求会傻等很久,整个循环就卡在那儿;给请求设个 timeout=5,5 秒没响应就判定它不通、进下一个,批量才跑得顺。这两点会在你第一次真正批量扫目标时教你做人。
五、常见错误
- 忘记在 while 里更新变量 → 死循环;
- 循环体没缩进/缩进不一致 → 报错;
- 遍历的同时修改集合可能出问题,初学者先避免。
这三条都值得展开说一句。第一条前面讲过:while 循环里一定要有"让条件变假"的动作,否则无限转。第二条是 Python 的老熟人——循环体必须缩进,忘了缩进或者这行缩进四格、那行缩进三格,运行就报 IndentationError;报错信息里常会告诉你"哪一行、期望缩进多少",照着它去对齐就行。第三条稍微高深:你一边用 for 遍历一个列表、一边往里面增删元素,Python 可能会"漏看"或"看错"某些元素,行为很怪;初学者阶段先记着"遍历时别同时改它,要改就先复制一份",等熟练了再深究。
六、本篇小结
- for 遍历集合/固定次数,while 条件为真就重复。
- range(n) 产生 0…n-1;while 要能结束、防死循环。
- break 跳出整个循环,continue 跳过本轮。
- 批量检测 = 循环遍历目标 + 对每个执行检查。
下一篇 0.29 讲函数,把常用逻辑打包复用。