原标题:Python趣味编程:如何定时发短信给Ta讲笑话

人一无聊,就会想:反正每天都要给Ta问候一声早安,为何不同时讲个笑话呢?如果能写个程序每天早上定时给Ta发一条问候早安同时讲一个笑话的短信该多好。

说干就干,走起!

笑话准备

笑话从哪里来?自己写肯定是不现实的。在这个「云」的时代,各种云都有,自然是不缺开放API的(大部分都是免费的)。随意一搜,果然被我找到一个接口。

根据它给的API可以获取它所有的笑话,关键代码如下:


这里简单做一下介绍:

urllib2是Python的一个获取URL的组件。他以urlopen函数的形式提供了一个非常简单的接口,具有利用不同协议获取URL的能力,同样提供了一个比较复杂的接口来处理一般情况。urllib2可用来完成以下功能:

1.获取Web页面

2.在远程http服务器上验证

3.额外数据请求,如表单提交(GET和POST)

4.异常处理

5.非http协议通信(如FTP)

它的详细操作可以查看官方文档:https://docs.python.org/2/library/urllib.html

发短信

笑话准备好了,那么怎么发短信到手机呢?类似上面小节,笔者想着肯定也有开放的API,但是这次就没那么幸运了,短信API都是要付费的,怎么办??苦思冥想不得其解,这个时候突然收到移动服务号的短信如图:


这提醒了笔者,移动的139邮箱要给用户收到的邮件发送短信提醒!!这就妙了,因为发邮件是不需要钱的,只需要发邮件到Ta的139邮箱就可以了,哈哈。关键代码如下:


这里用的是qq邮箱,一般的邮件服务器都会开放smtp,pop3,imap服务的端口给用户,让用户可以查询邮件或者发送邮件。这里发送邮件,所以使用smtp服务。Python 的smtplib库可以实现这一功能。

整合代码尝试,效果如下图:


可见不能完全显示,这是因为139邮箱免费版具有140字限制如图:


有两种办法解决,一是付费5块钱(还是不愿意!),二是把一个笑话分成三部分,分别放在发件人,主题和正文中,如下图:


还是不行,字数限制是个硬伤。那就从原来的从笑话列表里选择第一个笑话改为选择字数最少的一个。代码如下:

json_result = json.loads(content)
content_list = json_result['showapi_res_body']['contentlist']
minlen = 10000
for item in content_list:
if len(item['text'])
title = item['title']
text = item['text']
minlen = len(item['text'])


基本可行了,不过发多了过后腾讯会认为是垃圾邮件(汗)。完整代码(joke.py)如下:

# -*- coding: utf-8 -*-
'''
Created on 2016年1月22日
@author: 邱康
'''
import urllib2, json,sys,smtplib
from email.mime.text import MIMEText
reload(sys)
sys.setdefaultencoding('utf-8')#避免中文编码问题
mail_host="smtp.qq.com" #设置服务器
mail_user="************" #用户名
mail_pass="*********" #口令
mailto_list=['*******'] #邮件接受者
def send_mail(to_list,part1,sub,content):
#to_list:收件人;sub:主题;content:邮件内容;
me=part1+"" #hello
msg = MIMEText(content,_subtype='plain',_charset='utf-8')#创建一个实例,这里设置为纯文字格式邮件编码utf8
msg['Subject'] = sub #设置主题
msg['From'] = me #设置发件人
msg['To'] = ";".join(to_list)
try:
s = smtplib.SMTP() #实例化
s.connect(mail_host) #连接smtp服务器
s.login(mail_user,mail_pass) #登陆服务器
s.sendmail(me, to_list, msg.as_string()) #发送邮件
s.close()
return True
except Exception, e:
print str(e)
return False
if __name__ == '__main__':
appkey = "e2376cfbe3b27dff923ed61698839a67"
url = 'http://apis.baidu.com/showapi_open_bus/showapi_joke/joke_text?page=1'
req = urllib2.Request(url)
req.add_header("apikey", appkey)
resp = urllib2.urlopen(req)
content = resp.read()
if(content):
json_result = json.loads(content)
content_list = json_result['showapi_res_body']['contentlist']
minlen = 10000
for item in content_list:
if len(item['text'])
first_title = item['title']
first_text = item['text']
minlen = len(item['text'])
print 'title:'+first_title
print 'content:'+first_text
length = len(first_text)
part1 = first_text[0:10]
part2 = first_text[10:22]
part3 = first_text[22:length]
print part1,"+",part2,"+",part3
if send_mail(mailto_list,part1,part2,part3):
print "send msg succeed"
else:
print "send msg failed"
else:
print "get joke error"

定时任务

现在准备工作齐全了,就差最后一步定时发送了。Linux 提供了一个定时任务工具crontab,windows提供了一个定时任务工具叫做任务计划,不 过笔者的笔记本又不是随时连上网的,所以把这个脚本放在实验室的虚拟机上了(debian)。一般linux都预装有所以只需以下命令:

Vi /etc/crontab

在文件最后一行添加

30 7 * * * root python /root/joke.py

这样就能达到每天早上7:30 发送给Ta发短信的目的啦!

总结

程序员是一个很好的职业,虽然会比较累,不过只要有一双发现的眼睛和对生活的热情就能够用自己的知识给生活带来一些闪光点,比如你可以为不会上网的长辈爬取天气预报信息发送到手机短信顺便问候一声,相信长辈们都会很开心的。