wxpy 实现微信机器人

  wxpy 号称可能是最优雅的微信个人号 API, 它 在 itchat 的基础上,通过大量接口优化提升了模块的易用性,并进行丰富的功能扩展,并且可轻松调用Tuling机器人,搭建属于自己的聊天机器人。具体请参考 wxpy官方文档
  基础讲解直接看官方文档即可,非常简单明了,这里我就直接讲我简单实现的功能吧!

1. 查看消息撤回

def dlDoc(fPath, ra, content, flag):
    """
    download_document
    :param fPath: filePath
    :param ra: rawData
    :param content:
    :param flag:
    :return:
    """
    ra.get('Text')(fPath)
    bot.file_helper.send(content)
    if 4 == flag:
        bot.file_helper.send_image(fPath)
    elif 7 == flag:
        bot.file_helper.send_video(fPath)
    else:
        bot.file_helper.send_file(fPath)
    os.remove(fPath)

 监听代码:

@bot.register(except_self=False, run_async=True, enabled=True)
def handleReceiveMsg(msg):
    """
    监听消息
    :param msg: 匹配的消息对象
    :return:
    """
    raw = msg.raw  # 原始数据 (dict 数据)
    mss = msg.bot.messages  # 获取该bot所有messages
    le = len(mss)

    if raw['Status'] == 4:
        # 获取消息ID
        oldmsgid = re.search(re.compile('<msgid>(.*?)</msgid>', re.S), raw['Content']).group(1)

        for i in range(le - 1, -1, -1):
            if oldmsgid == str(mss[i].id):
                name = msg.chat.name
                if name is None or name == '':
                    name = msg.chat.nick_name
                if mss[i].type == 'Text':
                    bot.file_helper.send(name + '撤回了一条消息:' + mss[i].text)
                    break
                elif mss[i].type == 'Map':
                    bot.file_helper.send(name + '撤回了一个位置信息:' + mss[i].location['label'])
                    break
                elif mss[i].type == 'Card':
                    card = mss[i].card
                    name = card.name
                    if name is None or name == '':
                        name = card.nick_name
                    sex = str(card.sex)
                    if sex == '1':
                        sex = '男'
                    else:
                        sex = '女'
                    bot.file_helper.send(name + '撤回了一张名片:名称:' + name + ',性别:' + sex)
                    break
                elif mss[i].type == 'Sharing':
                    bot.file_helper.send(name + '撤回了一个分享:' + mss[i].url)
                    break
                elif mss[i].type == 'Picture':
                    dlDoc(mss[i].file_name, mss[i].raw, name + '撤回了一张图片,图片正在加载。。。')
                    break
                elif mss[i].type == 'Recording':
                    dlDoc(mss[i].file_name, mss[i].raw, name + '撤回了一条语音,语音正在加载。。。')
                    break
                elif mss[i].type == 'Attachment':
                    dlDoc(mss[i].file_name, mss[i].raw, name + '撤回了一个文件,文件正在加载。。。')
                    break
                elif mss[i].type == 'Video':
                    dlDoc(mss[i].file_name, mss[i].raw, name + '撤回了一个视频,视频正在加载。。。')
                    break

2. 查看课程表

 a) 数据结构:这个设计就有点糙了,简单粗暴的直接写在内存,大家可以来一个巧妙的数据库设计,hhh


day_dict = {
    0: '星期一',
    1: '星期二',
    2: '星期三',
    3: '星期四',
    4: '星期五',
    5: '星期六',
    6: '星期日',
}

classes = {
    0: {1: "", 2: "9:55-11:35AM B203 JAVA程序设计", 3: '', 4: '', 5: '18:00-21:00 A214 计算机网络/Java实验'},
    1: {1: "", 2: "9:55-11:35AM B213 技术经济学", 3: '', 4: '', 5: '18:00-21:00 A314 电子商务实验'},
    2: {1: "8:00-9-40 B203 药学英语", 2: "9:55-11:35AM B201 Matlab",
        3: '1:30-3.10 A214 matlab实验', 4: '3:25-5.10 A214 R语言实验', 5: '18:00-21:00 D207 药学信息学'},
    3: {1: "", 2: "9:55-11:35AM B201 项目管理", 3: '1:30-3.10 B201 电子商务', 4: '', 5: ''},
    4: {1: "", 2: "9:55-11:35AM B213 计算机网络", 3: '1:30-4:10 B201 GMP', 4: '', 5: ''}
}

  b) 事件监听代码:

@bot.register([file_helper], TEXT, except_self=False)
def reply_file_helper(msg):
    """
    课程表查询
    :param msg:
    :return:
    """
    if '课程表' in msg.text:
        weekday_id = localtime(time())[6]
        if weekday_id < 5:
            day_classes = classes[weekday_id]
            text = '今日课程:\r\n'
            for key, value in day_classes.items():
                if value:
                    text += (value + '\r\n')
            msg.reply(text)
        else:
            msg.reply('周末没有课哦!')
    else:
        return


embed()

3. 人脸检测

   a) 人脸检测运用开源库 dlib实现

#! /usr/bin/python
# _*_ coding: utf-8 _*_
__author__ = 'Jeffery'
__date__ = '2018/5/1 23:10'
import cv2
import numpy as np
import dlib


def rect_to_bb(rect):
    """
    :param rect: dlib 脸部区域检测输出
    :return: 返回一个矩形坐标
    """
    x = rect.left()
    y = rect.top()
    w = rect.right() - x
    h = rect.bottom() - y
    return x, y, w, h


def shape_to_np(shape, dtype="int"):
    """

    :param shape: dlib脸部特征检测的输出
    :param dtype:
    :return:
    """
    coords = np.zeros((68, 2), dtype=dtype)
    for i in range(0, 68):
            coords[i] = (shape.part(i).x, shape.part(i).y)

    return coords


def resize(image, width=1200):
    """

    :param image: 要检测的图片
    :param width:
    :return:
    """
    r = width * 1.0 / image.shape[1]
    dim = (width, int(image.shape[0] * r))
    resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
    return resized


def detect(image_file):
    """

    :param image_file: image_file_path
    :return:
    """
    count = 0
    image = cv2.imread('./imgs/'+image_file)
    # image = resize(image, width=1200)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    detector = dlib.get_frontal_face_detector()
    rects = detector(gray, 1)

    predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

    for (i, rect) in enumerate(rects):
        count += 1
        shape = predictor(gray, rect)

        shape = shape_to_np(shape)

        (x, y, w, h) = rect_to_bb(rect)

        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
        # cv2.putText(image, "Face #{}".format(i + 1), (x - 10, y - 10),
        #             cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

        for (x, y) in shape:
            cv2.circle(image, (x, y), 1, (0, 0, 255), -1)
    cv2.imwrite('./res_imgs/detect_res_'+image_file, image)
    return './res_imgs/detect_res_'+image_file, count


if __name__ == '__main__':
    detect('1.png')

  b) 事件监听
    这段代码必须指出的是它存在一定的问题,请慎用,有时间我再考虑一下性能问题

@bot.register(Friend, PICTURE, except_self=False, enabled=True)
def reply_pic(msg):
    file_name = msg.file_name
    if os.path.splitext(file_name) != '.gif':
        msg.get_file('./imgs/' + file_name)
        img_path, count = detect(file_name)
        if count > 0:
            msg.reply_image(img_path)
            msg.reply(u"检测到%d张人脸" % count)
        else:
            msg.reply(u'图片收到,没有检测到人脸')

4. 深夜提醒

 这个就简单啦

@bot.register(Friend, TEXT, except_self=True)
def reply_text(msg):
    """
    回复好友消息
    :param msg:匹配上的 消息对象
    :return: msg.reply
    """
    struct_time = localtime(time())
    if struct_time[3] >= 23 or struct_time[3] <= 7:
        now_time = strftime('%Y-%m-%d %H:%M:%S', struct_time)
        weekday = day_dict[struct_time[6]]
        msg.reply(u'[自动回复]现在是北京时间:' + now_time + " " + weekday +
                  ', 时间不早了早点休息,明早一看到消息主人会立刻给您回复')

5. Tuling机器人

 Tuling机器人的使用你只需要申请一个api_key即可以使用,当然你也可以用自己的语料库训练一个别致的聊天机器人。

bot = Bot(cache_path=False, console_qr=False)
tuling = Tuling(api_key='api_key')
@bot.register(Friend, TEXT, except_self=True)
def reply_text(msg):
    """
    回复好友消息
    :param msg:匹配上的 消息对象
    :return: msg.reply
    """
    tuling.do_reply(msg)

猜你喜欢

转载自blog.csdn.net/jeffery0207/article/details/80219034