Skip to content

Commit ffdbf7a

Browse files
committed
004-EmailNotify
1 parent a6efb49 commit ffdbf7a

File tree

4 files changed

+271
-0
lines changed

4 files changed

+271
-0
lines changed

004-EmailNotify/.gitignore

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
pip-wheel-metadata/
24+
share/python-wheels/
25+
*.egg-info/
26+
.installed.cfg
27+
*.egg
28+
MANIFEST
29+
30+
# PyInstaller
31+
# Usually these files are written by a python script from a template
32+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
33+
*.manifest
34+
*.spec
35+
36+
# Installer logs
37+
pip-log.txt
38+
pip-delete-this-directory.txt
39+
40+
# Unit test / coverage reports
41+
htmlcov/
42+
.tox/
43+
.nox/
44+
.coverage
45+
.coverage.*
46+
.cache
47+
nosetests.xml
48+
coverage.xml
49+
*.cover
50+
*.py,cover
51+
.hypothesis/
52+
.pytest_cache/
53+
54+
# Translations
55+
*.mo
56+
*.pot
57+
58+
# Django stuff:
59+
*.log
60+
local_settings.py
61+
db.sqlite3
62+
db.sqlite3-journal
63+
64+
# Flask stuff:
65+
instance/
66+
.webassets-cache
67+
68+
# Scrapy stuff:
69+
.scrapy
70+
71+
# Sphinx documentation
72+
docs/_build/
73+
74+
# PyBuilder
75+
target/
76+
77+
# Jupyter Notebook
78+
.ipynb_checkpoints
79+
80+
# IPython
81+
profile_default/
82+
ipython_config.py
83+
84+
# pyenv
85+
.python-version
86+
87+
# pipenv
88+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
90+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
91+
# install all needed dependencies.
92+
#Pipfile.lock
93+
94+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
95+
__pypackages__/
96+
97+
# Celery stuff
98+
celerybeat-schedule
99+
celerybeat.pid
100+
101+
# SageMath parsed files
102+
*.sage.py
103+
104+
# Environments
105+
.env
106+
.venv
107+
env/
108+
venv/
109+
ENV/
110+
env.bak/
111+
venv.bak/
112+
113+
# Spyder project settings
114+
.spyderproject
115+
.spyproject
116+
117+
# Rope project settings
118+
.ropeproject
119+
120+
# mkdocs documentation
121+
/site
122+
123+
# mypy
124+
.mypy_cache/
125+
.dmypy.json
126+
dmypy.json
127+
128+
# Pyre type checker
129+
.pyre/

004-EmailNotify/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# 监听玩客家平台币价变化,使用邮件通知
2+
3+
本小项目主要体现邮箱的作用,如果利用微信绑定收信邮箱,便能实时知道自己想要知道的信息。 注意:发送邮箱的登录密码一般是在设置smtp中生成的授权码。
4+
5+
- 在服务器上启动脚本,与连接无关:
6+
```shell
7+
nohup python main.py
8+
```

004-EmailNotify/main.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8 -*-
3+
"""
4+
@Description: 玩客家 币价变化,邮件通知 api
5+
@Date :2020/12/17
6+
@Author :xhunmon
7+
8+
"""
9+
import json
10+
import smtplib
11+
import time
12+
from email.mime.multipart import MIMEMultipart
13+
from email.mime.text import MIMEText
14+
15+
import requests
16+
from my_fake_useragent import UserAgent
17+
18+
ua = UserAgent()
19+
agent = ua.random()
20+
21+
22+
class Email(object):
23+
def __init__(self, from_user, pwd, to_other):
24+
"""
25+
:param from_user: 发送者邮箱号
26+
:param pwd: 发送者邮箱密码(非登录密码)
27+
:param to_other: 目标邮箱
28+
"""
29+
self.__from_user = from_user
30+
self.__pwd = pwd
31+
self.__to_other = to_other
32+
33+
def sendMsg(self, title="", content=""):
34+
print("%s向%s发送邮件:标题{%s}\t内容{%s}" % (self.__from_user, self.__to_other, title, content))
35+
retry = 0
36+
while True:
37+
print("【%s】开始发送,次数:%3d" % (title, retry))
38+
try:
39+
msg = MIMEMultipart()
40+
msg.attach(MIMEText(content, 'plain', 'utf-8'))
41+
msg['Subject'] = title
42+
msg['From'] = self.__from_user
43+
s = smtplib.SMTP_SSL("smtp.qq.com", 465) # 通过SSL方式发送,服务器地址和端口
44+
s.login(self.__from_user, self.__pwd) # 登录邮箱
45+
s.sendmail(self.__from_user, self.__to_other, msg.as_string()) # 开始发送
46+
print("邮件发送成功,发送时间【%s】" % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))))
47+
break
48+
except Exception as e:
49+
print(
50+
"邮件发送失败,5秒钟后重新发送,发送时间【%s】" % (time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))))
51+
print(e)
52+
retry += 1
53+
time.sleep(5)
54+
55+
56+
class Coin(object):
57+
def __init__(self, coin="", diff=3.0, sleep=3, reload=1 * 60 * 60, email: Email = None):
58+
self.__COIN = coin # 币名称
59+
self.__DIFF = diff # 当trend的值幅度差为该设定值,邮箱进行通知
60+
self.__SLEEP_TIME = sleep # 每次获取的睡眠时间
61+
self.__RELOAD_TIME = reload # 每小时重复更新一次页面
62+
self.__email = email
63+
self.__RINGE_COUNT = int(self.__RELOAD_TIME / self.__SLEEP_TIME)
64+
self.__is_release = False
65+
self.__last_price = 0.0
66+
self.__last_time = 0
67+
self.__last_trend = 0.0
68+
self.__is_first = True
69+
self.__URL = "https://app.wkj.pub/api/market/getMarketTradeJson" # 请求地址
70+
self.__DATA = 'market=%s_bitcny&sellnum=10&buynum=10&donenum=10' % coin.lower()
71+
self.__headers = {"user-agent": agent}
72+
73+
def start(self):
74+
print("thread【%2s diff is %2s , sleep is %2d ,retry time is %5ld】" % (
75+
self.__COIN, str(self.__DIFF), self.__SLEEP_TIME, self.__RELOAD_TIME))
76+
while True:
77+
try:
78+
time.sleep(self.__SLEEP_TIME)
79+
if self.__is_release:
80+
print("%2s 已释放,退出!" % self.__COIN)
81+
break
82+
req = requests.post(self.__URL, data=self.__DATA, headers=self.__headers)
83+
if req.status_code != 200:
84+
print("%2s 请求失败-%s" % (self.__COIN, req.status_code))
85+
continue
86+
data = json.loads(req.text)
87+
# print(req.text)
88+
price = float(data.get("data").get("new_price")) # 当前价格
89+
trend = float(data.get("data").get("change")) # 跌涨幅 趋势
90+
num = float(data.get("data").get("doneOrders")[0].get("num")) # 当前成交价
91+
done_time = int(data.get("data").get("doneOrders")[0].get("time")) # 当前成交价
92+
done_type = int(data.get("data").get("doneOrders")[0].get("type")) # 当前状态(1-buy,2-sell)
93+
if price <= 0:
94+
print("%2s 价格为0,没有获取到数据,跳过" % self.__COIN)
95+
continue
96+
if done_time == self.__last_time: # 没有最新成交的单
97+
print("【%2s …………】" % self.__COIN)
98+
continue
99+
status = "buy" if done_type == 1 else "sell"
100+
print("【%2s \t| %2s \t| %5s \t| %2s% \t| %2s】" % (
101+
self.__COIN, status, str(price), trend, str(num)))
102+
self.__last_price = price
103+
self.__last_time = done_time
104+
if self.__is_first: # 第一次启动就不必了
105+
self.__is_first = False
106+
self.__last_trend = trend
107+
print("【%2s __is_first】" % self.__COIN)
108+
continue
109+
temp_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
110+
if self.__last_trend - trend > self.__DIFF: # 跌了
111+
self.__last_trend = trend
112+
self.__email.sendMsg(
113+
"【%2s跌:%s | %s%】" % (self.__COIN, str(self.__last_price), str(trend)),
114+
str("【价格:%s,跌幅:%s%,时间:%s】" % (
115+
str(self.__last_price), str(trend), temp_time)))
116+
elif trend - self.__last_trend > self.__DIFF: # 涨了
117+
self.__last_trend = trend
118+
self.__email.sendMsg(
119+
"【%2s涨:%s | %s%】" % (self.__COIN, str(self.__last_price), str(trend)),
120+
str("【价格:%s,涨幅:%s%,时间:%s】" % (
121+
str(self.__last_price), str(trend), temp_time)))
122+
except Exception as e:
123+
print("wkj api【%2s】异常,5秒钟后重试!" % self.__COIN)
124+
print(e)
125+
time.sleep(5)
126+
print("【%2s 结束了】" % self.__COIN)
127+
128+
129+
if __name__ == "__main__":
130+
email = Email(from_user="[email protected]", pwd="bbb", to_other='[email protected]')
131+
eth = Coin(coin="ETH", diff=2, sleep=5, reload=2 * 60 * 60, email=email)
132+
eth.start()

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
- 003-电商关键词listing爬取策略 ——进行中
1313

1414

15+
- [004-EmailNotify:监听虚拟币变化,使用邮箱通知](./004-EmailNotify/README.md) ——已完成
16+
1517
----------
1618

1719
##### 声明:本项目仅用于学习交流,禁止任何商业用途,违者自承担相应法律责任!

0 commit comments

Comments
 (0)