定时给Ta讲笑话

定时给Ta讲笑话

大四的生活就是这么无聊,我琢磨着也学了这么多东西了,为啥不能用自己的知识来给生活找点乐子呢?我想反正每天都要给Ta问候一声早安,为何不同时讲个笑话呢?如果能写个程序每天早上定时给Ta发一条问候早安同时讲一个笑话的短信该多好。说干就干,走起~

笑话准备

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

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

appkey = "你自己申请的appkey"
url = 'http://apis.baidu.com/showapi_open_bus/showapi_joke/joke_text?page=1'#API地址
req = urllib2.Request(url) #初始化请求
req.add_header("apikey", appkey) #添加 http请求的header
resp = urllib2.urlopen(req) #发起请求
content = resp.read()#获得返回内容,json格式字符串
if(content):
    json_result = json.loads(content) #转换为字典对象
    #  下面从这个字典中获得笑话的标题和正文
    content_list = json_result['showapi_res_body']['contentlist']
    # 只取第一条笑话的标题和正文
    first_title = content_list[0]['title'].encode('utf8')
    first_text = content_list[0]['text'].encode('utf8')
    print '标题:'+first_title
    print '内容:'+first_text
else:
    print "error"
    

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

    1.获取Web页面
    
    2.在远程http服务器上验证
    
    3.额外数据请求,如表单提交(GET和POST)
    
    4.异常处理
    
    5.非http协议通信(如FTP)

它的详细操作可以查看官方文档

发短信

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

《定时给Ta讲笑话》

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

import smtplib,sys
from email.mime.text import MIMEText

mail_host="smtp.qq.com"      #设置服务器
mail_user="你的qq邮箱 "    #用户名
mail_pass="你的qq邮箱密码"           #密码

def send_mail(to_list,sub,content):                 
#to_list:收件人;sub:主题;content:邮件内容;
me="笑话来了"+"<"+mail_user+">"                   
#这里的hello可以任意设置,收到信后,将按照设置显示
    msg = MIMEText(content,_subtype='html',_charset='utf-8')    #创建一个邮件消息实例,这里设置为html格式邮件
    msg['Subject'] = sub    #设置主题
    msg['From'] = me  
    msg['To'] = ";".join(to_list)  
    try:  
        s = smtplib.SMTP              #实例化python邮件的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
        

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

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

《定时给Ta讲笑话》

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

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

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

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

如下图:

《定时给Ta讲笑话》
基本可行了,不过发多了过后腾讯会认为是垃圾邮件(汗),主要是发件人名字太奇怪了,大家有什么好主意可以告诉我一下啊,多多交流。
完整代码(joke.py)如下:

# -*- coding: utf-8 -*-
'''
Created on 2016年1月22日
@author: mageekchiu
'''
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+"<"+mail_user+">"  #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 = "你自己的appkey"
    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'])<minlen:
                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都预装有python环境所以只需以下命令:

Vi /etc/crontab

在文件最后一行添加

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

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

总结

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

更新-2016/3/4

最近发现 有好多发短信的服务 比如网易云信,leancloud等等,一条短信花不了1毛钱,就几分,所以一个月不到3块,还是可以买一下,毕竟这样就不需要考虑字数限制了,三块钱能让Ta开心一下还是非常不错的。

    原文作者:MageekChiu
    原文地址: https://segmentfault.com/a/1190000004539530
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞