基于Itchat开发一个生活机器人

摘要

在购买完VPS后琢磨着要用VPS干点啥,正巧天气转冷,琢磨弄一个脚本每天提醒自己当天的天气状况。下载状态提醒功能是后加功能,基于itchat搭建完平台后可以很方便的添加新的功能。

本文只介绍原理,具体项目请见:https://github.com/DreamReaperLEE/Robee itchat貌似已经被微信封了

itchat原理介绍

itchat是一个开源的微信个人接口,它可以模拟网页端的微信登陆。从而用Python脚本或命令行模式来使用个人微信号,达到推送各种通知到微信上的目的。包括推送天气信息、将你服务器上的各种动态推送到你的微信上。

总体设计思路

项目的目录结构为:

Robee:
│ bytime.py
│ chat_robot.py
│ check_aria2.py
│ film.py
│ LICENSE
└─│ weather.py

其中chat_robot为主文件,在该文件中初始化itchat,为各个查询脚本创建进程,并且统一调用itchat的send函数来进行消息的推送。

天气信息获取(weather.py)

中国天气有三个接口可以获取到天气信息数据,但是获取到的信息除了移动端接口获取到的当前温度信息是准的以外,其他接口得到的数据都明显不准确,所以放弃。

最终采用的是一个叫心知天气提供的API,可以查询未来几天的天气、空气质量、生活指数等,可以满足我们的基本需求。

获取到的数据为json数据,其api说明里对回复的json格式也做了相应说明。对数据整理后,整合为要推送的句子返回。

# get temperature information for three days
def get_temp():
    # use seniverse weather api,replace location with your city name
    c = urllib2.urlopen(
        'https://api.seniverse.com/v3/weather/daily.json?key=nyxro3e5cgrffpmz&location=haerbin&language=zh-Hans&unit=c&start=0&days=3')
    # analysis the result,you can view the json format @ https://api.seniverse.com/
    result = json.loads(c.read())
    # get city name
    city = result['results'][0]['location']['name'].encode('utf-8') + '天气预报😐'
    # today's temperature information
    today_json = result['results'][0]['daily'][0]
    # tomorrows temperature information
    day2_json = result['results'][0]['daily'][1]
    # the day after tomorrow
    day3_json = result['results'][0]['daily'][2]
    # create detail message,I'm Chinese.so there are lots of chinese
    today = '今日白天:' + today_json['text_day'].encode('utf-8') + ' 夜间:' + today_json['text_night'].encode(
        'utf-8') + '\n最高气温:' + today_json['high'].encode('utf-8') + '℃ 最低气温:' + today_json['low'].encode('utf-8') + '℃'
    day2 = '明日白天:' + day2_json['text_day'].encode('utf-8') + ' 夜间:' + day2_json['text_night'].encode(
        'utf-8') + '\n最高气温:' + day2_json['high'].encode('utf-8') + '℃ 最低气温:' + day2_json['low'].encode('utf-8') + '℃'
    day3 = '后日白天:' + day3_json['text_day'].encode('utf-8') + ' 夜间:' + day3_json['text_night'].encode(
        'utf-8') + '\n最高气温:' + day3_json['high'].encode('utf-8') + '℃ 最低气温:' + day3_json['low'].encode('utf-8') + '℃'
    # combine all message in one message
    msg = city + '\n' + today + '\n' + '😱😱😱😱😱😱😱😱😱😱\n' + day2 + '\n😱😱😱😱😱😱😱😱😱😱\n' + day3
    return msg

下载动态的推送(check_aria2.py)

本人采用的下载器为aria2,该下载器提供了一套json/rpc接口供web端界面进行管理,默认端口为6800.但是没有找到该接口API,随对该端口进行数据包抓取自己找api

可以很明显的看出其访问规则为

http://ip地址:6800/jsonrpc?tm=1504257059456

并且带有json格式的jsonrpc、id、method、params信息。

其中tm项据我观察是代表了相应的操作,tm=1504257059456代表的是获取已经停止的下载条目。其他tm值可以查看相应的数据包得到

在python里模拟web端发送该格式的信息,对获取到的信息进行整理,即可获得当前的下载完成项信息。

# check new download status
def update_complete():
    old_list = complete_list
    # init a new list
    new_list = []
    # same as the past function
    jsonreq = json.dumps({'jsonrpc': '2.0', 'id': 1, 'method': 'aria2.tellStopped', 'params': [0, 1000]})
    c = urllib2.urlopen('http://yourip:6800/jsonrpc?tm=1504257059456', jsonreq)
    result = json.loads(c.read())
    result = result['result']
    for every in result:
        name = every['files'][0]['path']
        if name == '':
            name = every['files'][0]['uris'][0]['uri']
        name = name.replace('/home/download/', '').encode('utf-8')
        status = every['status'].encode('utf-8')
        msg = '文件名:' + name + '\n状态:' + status
        new_list.append(msg)
    msg = 'no'
    # if new list is different from the old one,then create trend message
    if list(set(new_list).difference(set(old_list))):
        more = list(set(new_list).difference(set(old_list)))
        msg = '下载有新动态:'
        for every in more:
            msg = msg + '\n' + every + '\n'
    return msg, new_list

电影信息的推送(film.py)

采用beautifulsoup4进行开发,原理是利用爬虫进行指定网站的数据抓取,如果有新的电影就推送给我,网上教程一大堆就不多讲了,实现原理与下载推送有些类似。

使用图灵机器人(tuling.py)

将自己的微信机器人与图灵的API对接到一起,可以没事的时候和自己的机器人聊聊天,也挺有意思的。

首先在itchat中注册TEXT型消息的回复函数

@itchat.msg_register(itchat.content.TEXT)

其次在这个函数中,将传入的msg通过图灵api获取结果后return即可

def text_reply(msg):
    tulingapi……
    return result

图灵机器人的注册及api说明见网址:http://www.tuling123.com/

自定义消息回复类型(query_database.py)

但是由于图灵机器人目前来说还是不够智能,有的时候可以说回答是非常智障的。

于是在mysql中创建一个表,其内部只有三个变量,自增id,title和content。

在接受消息后,先通过查询函数数据库中是否有类似语句,有的话则回复该条语句,如果没有则交给图灵机器人来回复。

cur.execute("select * from own where title like '%s%s%s'" % ('%',msg,'%'))