我刚刚开始使用Python,在尝试使用Ardit Suice的课程时,我编写了以下代码来实现自定义网站拦截器:
#!/usr/bin/env python3
import time
import os
from datetime import datetime as dt
hosts_path = '/etc/hosts'
tmp_path = '/tmp/hosts.tmp'
site_list = [ 'www.facebook.com', 'mail.google.com']
def write_hosts():
hostfile = open(hosts_path, 'r')
filecont = hostfile.read()
hostfile.close
for site in site_list:
if not site in filecont:
try:
with open(hosts_path, 'a') as fh:
fh.write('127.0.1.1 ' + site + '\n')
print ("Wrote %s to hosts file %s" % (site, hosts_path))
except PermissionError:
print ("Sorry, you need to be admin to do this")
def write_fresh_hosts():
testfile = open(tmp_path, 'w')
hostfile = open(hosts_path, 'r')
line=hostfile.readline()
while line:
for site in site_list:
if not site in line:
testfile.write(line)
else:
print ("Deleting %s from our blocked list" % site)
line=hostfile.readline()
testfile.close
hostfile.close
os.rename(tmp_path, hosts_path)
while True:
print(1)
print (dt.now())
upper=dt(dt.now().year, dt.now().month, dt.now().day, 20, 0)
lower=dt(dt.now().year, dt.now().month, dt.now().day, 17, 0)
if lower <= dt.now() <= upper:
print ("Blocking now")
write_hosts()
time.sleep(5)
else:
print ("Checking website lists for already blocked sites:")
write_fresh_hosts()
time.sleep(5)
我想要做的是在指定的时间间隔内将一个站点列表写入hosts文件,如果超过这些时间,则删除这些行。
但是我发现我的hosts文件很快就变成了110MB大小,并且它只是重复了一遍又一遍地重复了127.0.0.1 localhost
行:
127.0.0.1 localhost
127.0.0.1 localhost
127.0.0.1 localhost
127.0.0.1 localhost
... (repeated)
在我的文件末尾,我找到了这些行:
127.0.1.1 www.facebook.com
127.0.1.1 mail.google.com
最初,hosts文件只包含单行:
127.0.0.1 localhost
输出:
sudo python siteblocker.py
Checking website lists for already blocked sites:
Checking website lists for already blocked sites:
... (repeated)
我哪里出错了?
答案 0 :(得分:1)
在这部分代码中:
while line:
for site in site_list:
if not site in line:
testfile.write(line)
else:
print ("Deleting %s from our blocked list" % site)
line=hostfile.readline()
您正在针对主机文件的每一行迭代site_list
。每次在site
内找不到给定的line
时,您都在撰写line
。由于site_list
中有两个条目,并且它们都不在您的localhost
行中,因此您每行都会写两次。
由于您随后将新生成的输出文件作为新的输入文件,因此每次调用时,您实际上会将文件中的行数加倍。