Skip to content

Commit 7980fa3

Browse files
author
littlelory
committed
天气提醒脚本 README
1 parent 151bdc2 commit 7980fa3

File tree

7 files changed

+161
-1
lines changed

7 files changed

+161
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
* [【工具类】HTTP请求工具类(apache httpclient)](https://github.com/LittleLory/codePool/blob/master/java/apache_HttpClient_PoolManager_demo.java)
99

1010
### python相关
11-
* [【小项目】汽车之家爬虫(scrapy)](https://github.com/LittleLory/codePool/tree/master/python/autohome_spider)
11+
* [【小项目】汽车之家爬虫(scrapy)](https://github.com/LittleLory/codePool/tree/master/python/autohome_spider)
12+
* [【小项目】天气提醒脚本](https://github.com/LittleLory/codePool/tree/master/python/weather_remind)

python/weather_remind/README.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# 天气提醒脚本
2+
3+
我讨厌下雨天,尤其是出门却没带伞的下雨天。每到这个时候,就特羡慕大头儿子,“人家有伞,我有大头”。。。既然没有大头儿子的天赋异禀,就只能老老实实地带伞了。
4+
5+
蛋,总是忘了带肿么破!!!
6+
7+
在多次被北京的大雨拍在路上之后,我痛定思痛,决定要想个法子解决忘带伞这一世纪难题。。。
8+
9+
其实这个问题很好解决嘛,早晨出门前看下天气预报不就行了。对于像我这种每天能够早早起床、舒展一会儿身体、做一顿营养早餐、看一个小时书、在上班路上欣赏北京美景的人来说so easy。
10+
11+
才怪。
12+
13+
每天睡的比猪晚、起的比猪早,早晨急忙爬起来刷个牙洗个脸,连个饭都吃不上就要去挤地铁,这还天天迟到呢!哪还能想起来去看天气预报啊!!!
14+
15+
主动去看天气预报这个方案对我来基本无解。。。
16+
17+
那,就被动好了,让基友在我需要带伞的时候,主动提醒我一下吧。
18+
19+
好,祭出基友之友--Python!!!
20+
21+
我想让python做以下事情:
22+
23+
![流程图](流程图.png)
24+
25+
所以,要实现以下三部分:
26+
27+
1. 爬取天气数据
28+
2. 判断是否有雨
29+
3. 发送提醒
30+
31+
嗯,开搞。
32+
33+
#### 爬天气预报数据
34+
先找个靠谱的天气预报网站,看了一圈,感觉这个[中国天气预报](http://www.weather.com.cn/weather/101010100.shtml)挺靠谱的,毕竟敢用“中国”命名呢。下图就是目标数据了:
35+
36+
![天气数据](天气数据.png)
37+
38+
打开浏览器控制台,找到数据在html中的位置:
39+
40+
![html1](html1.png)
41+
42+
可以看到,7天的天气数据位于 id="7d"的div标签 -> ul标签 -> li标签 中。
43+
44+
再看看li中的具体结构:
45+
46+
![html2](html2.png)
47+
48+
49+
* 日期位于 li标签 -> h1标签 中;
50+
* 天气位于 li标签 -> class="wea"的p标签 中;
51+
* 最高温度位于 li标签 -> class="tem"的p标签 -> span标签 中;
52+
* 最低温度位于 li标签 -> class="tem"的p标签 -> i标签 中。
53+
54+
数据找好了,开始爬数据出来。鉴于爬数据的逻辑简单,直接用urllib2和Beautifulsoup来做。
55+
56+
```
57+
# 爬取7天内的天气数据
58+
from bs4 import BeautifulSoup
59+
import urllib2
60+
def fetch_weather_datas():
61+
# 请求页面数据
62+
response = urllib2.urlopen(url='http://www.weather.com.cn/weather/101010100.shtml')
63+
body = response.read()
64+
65+
# 用BeautifulSoup解析,取出7天的天气数据
66+
soup = BeautifulSoup(body)
67+
tags = soup.select('#7d > ul > li')
68+
69+
return ['%s\t%s\t%s\t%s' % # 对七天的数据分别解析,将解析后的每天的数据拼接成“日期+天气+最高气温+最低气温”的字符串,\t分隔
70+
(
71+
tag.select('h1')[0].string, # 取时间数据
72+
tag.select('.wea')[0]['title'], # 取天气数据
73+
tag.select('.tem > span')[0].string, # 取最高气温
74+
tag.select('.tem > i')[0].string # 取最低气温
75+
)
76+
for tag in tags] # 返回结果为List
77+
```
78+
79+
#### 今天是否有雨?
80+
拿到天气数据之后,要看下今天的天气如何,是否需要提醒我带伞。
81+
82+
```
83+
# 传入爬到的天气数据,判断今天是否是雨天
84+
def is_rainy_day(weather_datas):
85+
return '雨' in weather_datas[0] # weather_datas[0]为今天的数据
86+
```
87+
88+
#### 发送提醒
89+
因为我手机上的邮件客户端始终在后台开启,选择用邮件的方式来做提醒比较合适,所以使用了Python自带的邮件发送工具:smtplib。
90+
需要有一个发送提醒邮件的邮箱账号,我用的是新浪的邮箱。
91+
92+
```
93+
# 发送邮件
94+
import smtplib
95+
from email.mime.text import MIMEText
96+
from email.header import Header
97+
def send_mail(receivers, datas):
98+
mail_host = 'smtp.sina.com' # 设置服务器,不同的邮箱对应的smtp服务器地址不同
99+
mail_user = 'username' # 用户名,发送邮件的邮箱账号的用户名
100+
mail_pass = 'password' # 密码,发送邮件的邮箱密码
101+
102+
# 定义邮件内容
103+
message = MIMEText('\n'.join(datas), 'plain', 'utf-8') # 邮件内容为爬取到的近7天天气数据
104+
message['From'] = Header(mail_user) # 邮件的发送方
105+
message['To'] = Header(','.join(receivers), 'utf-8') # 邮件的接受方,逗号分隔
106+
message['Subject'] = Header('天气提醒', 'utf-8') # 邮件主题
107+
108+
try:
109+
smtpObj = smtplib.SMTP()
110+
smtpObj.connect(mail_host, 25) # 连接服务器, 25 为新浪邮箱 SMTP 端口号
111+
log('连接服务器成功..')
112+
smtpObj.login(mail_user, mail_pass) # 登录服务器
113+
log('登录邮箱服务器成功..')
114+
smtpObj.sendmail(from_addr=mail_user, to_addrs=receivers, msg=message.as_string()) # 发送邮件
115+
log('邮件发送成功..')
116+
except smtplib.SMTPException as e:
117+
log('无法发送邮件...' + e.message)
118+
119+
120+
# 日志打印
121+
import time
122+
def log(msg):
123+
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
124+
print '[%s] %s' % (timestamp, msg)
125+
```
126+
127+
#### 整合
128+
将上边编写完成的方法按下边的方式整合到一起,就是一个能够发送天气提醒的脚本了:
129+
130+
```
131+
try:
132+
weather_datas = fetch_weather_datas() # 爬取天气数据
133+
if is_rainy_day(weather_datas): # 今天是否是雨天
134+
send_mail('[email protected]', weather_datas) # 发送天气数据到目标邮箱
135+
else:
136+
log('今天天气良好..')
137+
except:
138+
log('出错..')
139+
```
140+
141+
#### 定时执行
142+
写完脚本后,我希望这个脚本能在每天早晨6点30分执行,这样我就能在醒来的第一时间就能看到提醒邮件并带上雨伞了。
143+
144+
首先需要一个能联网的服务器,将脚本放在服务器中。
145+
146+
然后,用crontab来做定时的任务(linux环境)。执行:
147+
148+
`crontab -e`
149+
150+
此时会进入进入vim界面,进入编辑模式,输入:
151+
152+
`30 6 * * * /usr/bin/python xxxx/weather.py >> run.log`
153+
154+
保存,此时定时任务就跑起来了,日志记录在run.log文件中。
155+
156+
> 具体的cron表达式语法在网上有很多教程,就不细说了。
157+
158+
#### 完成
159+
不必再羡慕大头儿子了!虽然他有大头,但是我有伞啊~
154 KB
Loading
98.8 KB
Loading
11.2 KB
Loading
153 KB
Loading
39.9 KB
Loading

0 commit comments

Comments
 (0)