##背景
最近正在自学Python,找点有意思的小项目练练手。从知乎一帖子中学习到一位高手的撩妹技巧:每天定时给女朋友发一封邮件,简单的问候加天气情况。博主觉得有点意思,何不尝试做一下呢。
##原理
实现的原理很简单了。
调用免费的天气API接口,获取所在城市的天气情况 大家都知道Bing的背景图非常漂亮,每天都会更新,Bing也将获取图片的API公开。所以调用Bing每日图片的API,下载到本地 将天气情况和图片拼成邮件内容,利用python的smtp模块实现邮件发送 将python程序,即.py文件上传到服务器上。在crontab中加入一条定时任务,每天定时执行小程序。 主要过程如上所述,是不是非常简单。下面将Python代码放出。
##代码
# coding=utf-8
import urllib
import urllib2
from email import encoders
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
import xml.etree.ElementTree as ET
import time
import json
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((
Header(name, 'utf-8').encode(),
addr.encode('utf-8') if isinstance(addr, unicode) else addr))
# 获取bing的每日图片,修改api中的参数n,可以获取多张图片
# 从bing的api返回的xml中提取图片的url,然后下载到本地,并命名为yyyymmdd.jpg
def get_bing_pic():
req = urllib2.Request("http://cn.bing.com/HPImageArchive.aspx?idx=0&n=1")
webpage = urllib2.urlopen(req)
root = ET.fromstring(webpage.read())
# 获取图片链接
url = 'http://cn.bing.com' + root.find('image').find('url').text
# 图片描述
pic_desc_ = root.find('image').find('copyright').text
# 图片保存到本地的位置,这是linux的文件目录,windows的注意修改为C:/XX/XX
pic_file_name_ = "/root/" + time.strftime('%Y%m%d', time.localtime(time.time()))
urllib.urlretrieve(url, pic_file_name_ + url[-4:])
return pic_file_name_ + url[-4:], pic_desc_
# 调用免费的天气API接口,city_code默认为广州的code,其他城市code参见文末参考链接3.
def get_city_weather(city_code='101280101'):
response = urllib2.urlopen("http://www.weather.com.cn/data/cityinfo/"+city_code+".html")
weather_json = json.loads(response.read())
city_ = weather_json['weatherinfo']['city']
min_temp_ = weather_json['weatherinfo']['temp1']
max_temp_ = weather_json['weatherinfo']['temp2']
weather_ = weather_json['weatherinfo']['weather']
return city_, min_temp_, max_temp_, weather_
# 发件人地址和密码
from_addr = 'XXXX@XX.com'
password = 'XXXXXXX'
# SMTP服务器地址:
smtp_server = 'smtp.XXXX.com'
# 收件人地址:
to_addr = 'XXXXXXXX@XXX.com'
# 抄送给自己:
cc_addr = 'XXXXXX@XX.com'
city, min_temp, max_temp, weather = get_city_weather()
# 带路径的文件名
pic_file_name, pic_desc = get_bing_pic()
# 文件名
pic_name = pic_file_name.split("/")[-1]
# 这里是邮件正文内容,''是为了将附件的图片插入邮件正文中,直接显示
content = u"
Hello
%s今天天气%s,最低温度%s,最高温度%s.
\%s
Have a nice day.\
" % (city, weather, min_temp, max_temp, pic_desc, pic_desc)
msg = MIMEMultipart()
msg['From'] = _format_addr(from_addr)
msg['To'] = _format_addr(to_addr)
msg['Cc'] = _format_addr(cc_addr)
msg['Subject'] = Header(u'每日天气播报', 'utf-8').encode()
msg.attach(MIMEText(content, 'html', 'utf-8'))
# 添加附件就是加上一个MIMEBase,从本地读取一个图片
with open(pic_file_name, 'rb') as f:
# 设置附件的MIME和文件名,这里是jpg类型
mime = MIMEBase('image', 'jpg', filename=pic_name)
# 加上必要的头信息
mime.add_header('Content-Disposition', 'attachment', filename=pic_name)
mime.add_header('Content-ID', '<0>')
mime.add_header('X-Attachment-Id', '0')
# 把附件的内容读进来
mime.set_payload(f.read())
# 用Base64编码
encoders.encode_base64(mime)
# 添加到MIMEMultipart
msg.attach(mime)
server = smtplib.SMTP(smtp_server, 25) # SMTP协议默认端口是25
# server.starttls() #SSL加密的SMTP,注意修改端口号
server.set_debuglevel(1) # 打印和邮件服务器交互的详细信息
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr, cc_addr], msg.as_string())
server.quit()
##参考链接