-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathWebMonitor.py
More file actions
77 lines (64 loc) · 2.29 KB
/
WebMonitor.py
File metadata and controls
77 lines (64 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import logging
import requests
import sched
import functools
import hashlib
import sys
from requests.exceptions import RequestException
logger = logging.getLogger(__name__)
class WebMonitor:
def __init__(self, url, parsers, changed_callback=None, interval=None, headers=None, last_data=None):
self.url = url
self.parsers = parsers or []
def noop(*args, **kwargs): return None
self.changed_callback = changed_callback if callable(changed_callback) else noop
self.interval = interval if interval else 3*60
self.headers = headers
self.last_data = last_data
self.scheduler = sched.scheduler()
self.even = None
self.sched_continue = functools.partial(self.scheduler.enter, self.interval, 1, self.request)
def request(self):
# url为空 或 parser为空直接跳过
if not all((self.url, all((self.parsers),))):
return
# 发送请求并解析
try:
content = requests.get(self.url, headers=self.headers).content
for parser in self.parsers:
content = parser.parse(content)
except KeyboardInterrupt:
sys.exit(1)
except RequestException as e:
logger.warning(e)
self.even = self.sched_continue()
return
except Exception as e:
logger.warning(e)
content = None
# 检查变更并通知
if self.update_data(content):
logger.info('data change to: ' + (content or ''))
try:
self.changed_callback(content)
except KeyboardInterrupt:
sys.exit(1)
except Exception as e:
logger.warning(e)
self.even = self.sched_continue()
def update_data(self, data):
if isinstance(data, str):
data = data.encode()
hash = hashlib.sha256(data).hexdigest() if data else None
if self.last_data != hash:
self.last_data = hash
return True
else:
return False
def start(self):
# self.even = self.sched_continue()
self.scheduler.enter(0, 1, self.request)
self.scheduler.run()
def stop(self):
if self.even is not None:
self.scheduler.cancel(self.even)