有个需求需要记录办公室的公网IP来做校验,思路如下

  • 请求接口获取到本地公网IP
  • 打开本地存储IP的文件与接口获取的IP比对,如果一致不做操作,不一致则写入覆盖本地文件,并存入redis中

先看下比对操作的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
ip = []
with open("local_ip", mode="r", encoding="utf-8") as f:
file_ip = f.read()

if file_ip == browser_ip:
print(datetime.datetime.now(), "IP normal!", file_ip)
else:
print(datetime.datetime.now(), "IP Change!", browser_ip)
with open("local_ip", mode="w", encoding="utf-8") as f1:
f1.write(browser_ip)
ip.append(browser_ip)
ip.append("192.168.1.137")
json_ip = json.dumps(ip)

这段代码在编辑里以及服务器上手动执行的时候是没问题的,但是加入定时任务时,else里的写入操作是不执行的,即便当我手动修改文件local_ip时,在文件比对时还是会打印IP normal!

查找资料后终于知道了原因,先open一个文件时,这时句柄已经从文件的开头跑到文件的末尾了,再次打开的时候就是从文件末尾开始,所以就会获取不到文件内容

知道原因后就好修改了,

  • (方法1)在第二次打开文件的时候,将文件句柄重新放到开头即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ip = []
with open("local_ip", mode="r", encoding="utf-8") as f:
file_ip = f.read()

if file_ip == browser_ip:
print(datetime.datetime.now(), "IP normal!", file_ip)
else:
print(datetime.datetime.now(), "IP Change!", browser_ip)
with open("local_ip", mode="w", encoding="utf-8") as f1:
f.seek(0) # 把文件句柄重新放到开头
f1.write(browser_ip)
ip.append(browser_ip)
ip.append("192.168.1.137")
json_ip = json.dumps(ip)
  • (方法二) 在读文件的时候就只读指定行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

ip = []
with open("local_ip", mode="r", encoding="utf-8") as f:
try:
file_ip = f.readlines() # 读取文件全部内容,只选择第一行内容
print(file_ip[0])
except IndexError:
print("文件为空!")

if file_ip[0] == browser_ip: # 读取文件全部内容,只选择第一行内容
print(datetime.datetime.now(), "IP normal!", file_ip[0])
else:
print(datetime.datetime.now(), "IP Change!", browser_ip)
with open("local_ip_0", mode="w", encoding="utf-8") as f1:
f1.write(browser_ip)
ip.append(browser_ip)
ip.append("192.168.1.137")
json_ip = json.dumps(ip)