简要介绍一下要实现的功能。
在特殊时期,领导要求监控全校主要网站有没有被篡改,手动浏览太二,python实现每分钟自动检测几百个网页是否有变化,如果有变化就推送一条消息到微信群里。
主要方法:
本来想着每分钟保存一个页面到本地,然后和一分钟前保存的页面做对比,这样效率低且浪费资源。上网查了发现可以通过md5加密算法把页面加密成一个32位的字符串,每次对比字符串是否一致即可。具体原理不再赘述,可以参考https://blog.csdn.net/qq_28168421/article/details/82922071
关于微信推送消息,网上查到的itchat模块,试了觉得不安全,而且实测非常不稳定,掉线情况严重,链接https://blog.csdn.net/idealcitier/article/details/78503743,有兴趣的同学可以研究。
我这里用一种笨办法,利用selenium控制火狐浏览器,扫码登陆网页版qq,找到页面文本框元素,发送内容和回车键。需要用到python里selenium、火狐浏览器驱动甚至pip的安装和使用方法请自行查找。
上代码:
第一个文件:monitor.py (代码主要来自https://blog.csdn.net/qq_28168421/article/details/82922071对比md5值部分稍做了修改。)
这里图懒省事,直接把这整个文件放到一个函数里供主程序调用。程序末尾会return有变化的网站链接。
注:只能监控静态页面,动态页面无法使用。
def fuckweb():
import os
import hashlib
import urllib.request
import json
import codecs
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
#输入网址
site = [
'http://www.tsinghua.edu.cn/publish/thu2018/index.html',
'https://www.pku.edu.cn/',
'http://www.fudan.edu.cn/2016/index.html/',
'http://www15.zzu.edu.cn/',
]
#检查json档案是否存在,若没有就创建一个
try:
my_file = open('sitechange.json')
except IOError:
data = {}
with open('sitechange.json','w') as outfile:
json.dump(data, outfile, ensure_ascii = False)
#开启json档案,读入资料
with open("sitechange.json") as infile:
data = infile.read()
local_data = json.loads(data)
#检查json档案中是否有相关网址记录,没有则建立一个
for i in range(len(site)):
if site[i] not in local_data:
local_data[site[i]] = ""
#若用户删除网址记录,则更新json档案
temp = local_data.copy()
for i in local_data.keys():
if i not in site:
temp.pop(i)
local_data = temp
reback = []
#读入相关网址,并找出琦杂凑值,与已存储的杂凑值进行对比
for i in range(len(site)):
try:
remote_data = urllib.request.urlopen(site[i]).read()
remote_hash = hashlib.md5(remote_data).hexdigest()
except: #如果获取不到网站,比如404或根本打不开,抛出异常。
remote_hash = '00000000'
if remote_hash != local_data[site[i]]:
reback.append(site[i])
local_data[site[i]] = remote_hash
#把更新的杂凑值写回json档
with open('sitechange.json', 'w') as outfile:
json.dump(local_data, outfile, ensure_ascii = False)
return reback
第二个文件:main.py (代码主要自己瞎编的)
webdriver模块自动打开火狐浏览器,人工手动扫码登陆微信点开一个要发送消息的对话框,之后每分钟会调取第一个文件中的函数检测页面有没有变化,如果有就返回过来,通过浏览器发送到微信群里。每循环一次,将日志print到cmd上。
import time
import importlib
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
import time
import string
import monitor
#打开火狐浏览器,打开wx.qq.com,留15s时间来扫码登陆
bo = webdriver.Firefox()
bo.get('https://wx.qq.com/')
time.sleep(15)
d = '[]'
#循环开始,这里可以根据需求设置循环次数
for x in range(0,18720):
if x == 0:
ipa = zmonitor.fuckweb() #第一次循环不做汇报。
else:
ipa = monitor.fuckweb()
ipa = str(ipa)
ipa = ipa.translate(str.maketrans("'"," ")) #将'都转换成空格
d = ipa
if ipa != '[]':
a = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) #获取时间
ipb = ipa + '该网站于' + a + '有更新'
bo.find_element_by_id('editArea').send_keys(ipb) #定位微信网页文本输入区域,发送消息上去
bo.find_element_by_id('editArea').send_keys(Keys.ENTER) #定位微信网页文本输入区域,发送回车键
x += 1
# 以下内容用于记录日志,懒省事直接print到cmd。也可以写入日志文件。
b = 18720-x
ti = str(x)
ti2 = str(b)
a = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
if d == '[]':
final = a + '完成第' + ti + '次循环,未发现问题,剩余' + ti2 + '次'
print (final)
else:
final = a + '完成第' + ti + '次循环,剩余' + ti2 + '次 发现问题如下!!\n' + d + '该网站于' + a + '有更新'
print (final)
#时间间隔60s
time.sleep(60)
实际运行效果如下:
本文完。可加qq交流402243155