Python hosts文件站点解锁循环异常:单次仅删除一个站点
问题分析与修复方案
嘿,我一眼就揪出你代码里的问题了,咱们一步步拆解清楚:
核心问题:遍历列表时删除元素导致索引混乱
你那段解锁站点的循环逻辑有个典型的Python坑:在遍历lines列表的同时直接删除元素:
for l in lines: if "#" not in l: del lines[lines.index(l)]
举个例子,假设lines是[行A, 行B, 行C],第一次循环拿到行A并删除后,列表变成[行B, 行C]。下一次循环会直接取原列表的第二个元素(现在的行C),直接跳过了行B——这就是为什么每次tick只能删掉一部分内容,循环过程中列表结构变了,大量元素被跳过。
另外还有个隐藏bug:你现在的逻辑是删除所有不带#的行,这会把hosts文件里原本正常的条目(比如127.0.0.1 localhost)也删掉,这可太危险了!咱们得精准删除那些咱们之前添加的拦截条目,也就是包含redirect和目标域名的行。
修复后的完整代码
我帮你重写了关键逻辑,解决了这两个问题:
import time hosts_path=r"C:\Windows\System32\drivers\etc\hosts" redirect="127.0.0.1" # 注意:hosts文件只存域名,去掉https://前缀 website_list=["www.facebook.com","www.gmail.com","mail.google.com","www.youtube.com","www.helsebiblioteket.no"] while True: current_time = int(time.strftime("%H%M")) if 2100 <= current_time <= 2200: print("拦截模式已开启") with open(hosts_path,'r+') as hosts: content=hosts.read() for website in website_list: if website not in content: hosts.write(f'\n{redirect} {website}\n') else: print("解锁模式已开启") with open(hosts_path,'r') as hosts: lines = hosts.readlines() # 创建新列表存储需要保留的行,避免遍历中修改原列表 new_lines = [] for line in lines: stripped_line = line.strip() # 只跳过我们添加的拦截行:以redirect开头且域名在列表中 is_block_line = False if stripped_line.startswith(redirect): domain = stripped_line.split()[1] if domain in website_list: is_block_line = True # 保留非拦截行和注释行 if not is_block_line: new_lines.append(line) # 写入过滤后的内容 with open(hosts_path,'w') as hosts: hosts.writelines(new_lines) time.sleep(5)
关键修复点
- 避免遍历中修改列表:创建一个新的
new_lines列表,只保留需要的行,彻底解决索引混乱的问题。 - 精准匹配拦截行:只删除以
redirect开头且域名在website_list里的行,不会误删hosts里的正常系统条目。 - 清理网站列表:去掉了列表里的
https://前缀,因为hosts文件只识别纯域名,这样能保证匹配准确。
这样修改后,每次进入解锁模式时,所有拦截条目会一次性被清理干净,再也不会出现多次tick才完成的情况啦!
内容的提问来源于stack exchange,提问作者Khalil El Bayad
相关产品推荐
相关产品推荐

