wxpy 号称可能是最优雅的微信个人号 API, 它 在 itchat 的基础上,通过大量接口优化提升了模块的易用性,并进行丰富的功能扩展,并且可轻松调用Tuling机器人,搭建属于自己的聊天机器人。具体请参考 wxpy官方文档
基础讲解直接看官方文档即可,非常简单明了,这里我就直接讲我简单实现的功能吧!
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('(.*?) ', 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
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()
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'图片收到,没有检测到人脸')
这个就简单啦
@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 +
', 时间不早了早点休息,明早一看到消息主人会立刻给您回复')
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)