基于python以及AIUI WebSocket,WeChatPYAPI實作的微信聊天機器人
做此文的目的首先是學習Markdown的用法哈哈哈哈,其實也是記錄自己學習的一個程序,
以后我也會將自己在影像處理,計算機視覺的所學以及實踐實戰的process上傳到這個網站,不為一種做筆記的方式,
1.專案實施歷程
首先尋找微信與python的介面API(實作python驅動微信),當初有個想法利用os模塊直接驅動,但發現會占用外設,故不可行,于是google到了一個及其小眾的微信介面,看著介紹檔案感覺挺好入門的,于是用了起來,后續介紹不足,檔案地址:點擊進入,需要從github上下載zip然后本地瀏覽器打開,
其次,通過該檔案的介紹,我們得到了我們能通過該API得到的資訊:
1.微信訊息型別(語音or文本or轉賬收賬or好友申請)
2.微信訊息來源ID
以上為最主要以及我們需要利用到的,其他get可自行查看檔案
另外就是尋找處理資訊的機器人,首先找到的是圖靈機器人,畢竟網上大量的呼叫實體可供學習,但要錢,最后看中了科大訊飛的機器人,檔案地址:點擊進入
然后分別呼叫兩者的API就可完成專案了,是不是很簡單?
2.具體步驟
1.環境準備
environment:
python-version --3.7or3.8
packages:
1.psutil
2.ws4py
3.uuid
4.json
5.似憾訓有個,到時你debug時如果有module_error的話應該有提示你缺哪個
應該差不多了,還有些內置庫我就懶得寫了,待會看代碼你就知道怎么匯入了,
或許你不會下載庫?可以CSDN搜搜教程,啥都說這能寫上萬個字,
2.pyd匯入
由于該微信API未開源,只是提供了免費版來吸引你充錢購買付費版,我們只能引入其pyd檔案,從剛剛的zip包匯入適應你py版本以及os版本的pyd檔案(加密的py檔案,我們需要呼叫其中的方法),
比如,我是64位windows,python3.7的環境,那么,我在我的專案檔案中應該包含(我用的是vs):
同時我們要搞清楚這個pyd檔案中到底包含什么方法,
我們再demo中運行一下代碼:
import pyd檔案名
print(help(pyd檔案名))
便可以了解所有封裝好的方法了,但無法查看源代碼哈!!!
運行后可以得到:
3.代碼匯入
接下來就是大家都想要的代碼片段了,具體功能還未完全完善,但不是我的問題,總結再說,
首先是百度智能云語音識別api介面(百度的語音識別實在沒辦法,太強了,我的處理方式是準備設定一個pcm可覆寫式的存入語音資訊然后傳遞給api進行百度語音識別然后接入科大訊飛的機器人語意識別進行訊息回復的),
baiduapi.py
import os
from aip import AipSpeech
APP_ID=''#自己填入百度智能云注冊的app_id
API_KE=''#follow above
SECRET_KEY=''#follow above
client=AipSpeech(APP_ID,API_KE,SECRET_KEY)
def get_file_path(filepath):
with open(filepath,'rb') as f:
return f.read()
def write_srtxt(txtfile,line):
with codecs.open(txtfile,'a','utf-8') as f:
f.seek(0)#重定位
f.write(line)
def dt_sr(srcfile):
speechrate=16000
speechsaccu=16
buffer=get_file_path(srcfile)
sizepersec=int((speechsaccu/8)*speechrate)
timesec=int(len(buffer) / sizePerSec)
timeMinute = int((timeSec + 59) / 60)
print(timeMinute)
for count in range(0, timeMinute):
print(min((count + 1) * sizePerSec * 60, len(buffer)))
speechBuffer = buffer[count * sizePerSec * 60: min((count + 1) * sizePerSec * 60, len(buffer))]
result = client.asr(speechBuffer, 'pcm', 16000, {
'lan': 'zh',
})
if (result['err_no'] == 0):
print(result['result'])
line = str(count)+':00'+"--"+str(count)+":59 " + result['result'][0] +'\n'
#功能拓展輸入到機器人中
write_srtxt(txtFile, line)
#匯入傳入方法
else:
# print(result)
print("語音識別錯誤,錯誤碼是: ", result['err_no'], " , 錯誤資訊是:" + result['err_msg'])
pcmFile = 'd:\\workroom\\testroom\\sr.raw'
txtFile = 'd:\\workroom\\testroom\\srtxt.txt'
cmd = "ffmpeg -i " + pcmFile + " -f s16le -ar 16000 -acodec pcm_s16le -b:a 16 -ac 1 -y " + pcmFile
os.system(cmd)
dt_sr(pcmFile)
這里當初是準備wechat接好后再完善的,但那邊不行了,就沒有寫,這里相當于一個demo,將本地檔案語音識別,所以也就沒有封裝成方法進行呼叫了,需要的話大家可以自行改改,也不難,
另一個就是科大訊飛機器人websocket介面,用來處理訊息的:
xunfei.py
from ws4py.client.threadedclient import WebSocketClient
from baiduapi import *
import base64
import hashlib
import json
import time
import uuid
class wsapiclient(WebSocketClient):
def __init__(self,msgs,flag):
#msgs是訊息
#flag=0代表文本訊息,1代表語音訊息
super(wsapiclient,self).__init__()
self.msgs=msgs
self.flag=flag
def opened(self):
pass
def closed(self,code,reason):
if code==1000:
print('link cancel')
else:
print('link close uncommonly:'+str(code)+",reason:"+str(reason))
#就是處理訊息以及反饋訊息的程序
def received_message(self, m):
cjson=checkJSON()
re_msg=''#初始化回復訊息
s=json.loads(str(m))#將互動語言作為傳入資料
if s['action']=="started":#建立通信階段
try:
if self.flag==0:#接收到文本訊息
self.send(self.msgs)
end_tag='--end--'
self.send(bytes(end_tag.encode("utf-8")))
print('結束標志已經發送')
if self.flag==1:#接受到語音訊息
#放入百度語音識別中進行決議得到msg
baidu_shibie(self.msgs)
self.send(self.msgs)
end_tag='--end--'
self.send(bytes(end_tag.encode("utf-8")))
print('結束標志已經發送')
elif s['action']=="result":#說明訊息已經接受到了,需要回傳了
data=s['data']
#判斷反饋訊息的型別(我們只需要語意結果)
try:
if data['sub']=="nlp" :
if data['intent']['rc']==0:#理解話了
re_msg=data['intent']['answer']['text']
else:
re_msg='小汪很菜,沒給我開發好,不知道怎么回答你'
except:
if data['rc']==0:
re_msg=data['text']
else:
pass
return re_msg
def get_auth_id():
mac=uuid.UUID(int=uuid.getnode()).hex[-12:]
return hashlib.md5(":".jion([mac[e:e+2]for e in range(0,11,2)]).encode("utf-8")).hexdigest()
def get_conparam(flag):
#構造握手引數(建立連接)
url='ws://wsapi.xfy.cn/v1/aiui'#建立post連接
app_id=''
app_key=''
curtime=int(time.time())
auth_id=get_auth_id()
param_0="""{{
"auth_id":"{0}",
"result_level":"plain",
"data_type":"text",
"scene":"main_box",
"sample_rate":"16000",
"ver_rate":"monitor"
"clean_dialog_history":"user",
"close_delay":"200",
"context": "{{\\\"sdk_support\\\":[\\\"iat\\\",\\\"nlp\\\",\\\"tts\\\"]}}"
"""
param_1="""{{
"auth_id":"{0}",
"result_level":"plain",
"data_type":"audio",
"scene":"main_box",
"sample_rate":"16000",
"ver_rate":"monitor"
"clean_dialog_history":"user",
"close_delay":"200",
"context": "{{\\\"sdk_support\\\":[\\\"iat\\\",\\\"nlp\\\",\\\"tts\\\"]}}"
"""
def get_param(param):
param=param.format(auth_id).encode("utf-8")
parambase64=base64.b64encode(param).decode()#轉碼,轉為我們所需要傳入引數的格式
checksumpre=api_key+str(curtime)+parambase64
checksum=hashlib.md5(checksumpre.encode("utf-8")).hexdigest()
connparam="?appid="+aapp_id+"&""&checksum=" + checksum + "¶m=" + paramBase64 + "&curtime=" + str(
curTime) + "&signtype=md5"
return connparam
if flag==0:
connparam=get_param(param_0)
elif flag==1:
connparam=get_param(param_1)
url=url+connparam
return url
最后就是微信api了,我將其設定為啟動檔案(就是說他含有Mian函式),
#encoding=utf-8
#負責與微信進行訊息的通道交接
#作為主函式啟用
from xunfei import *
import os
import psutil
from WeChatPYAPI import WeChatPYApi
from queue import Queue
import logging
import time
#匯入微信的介面API
#定義訊息堆疊
queue_message=Queue()
#設定日志
logging.basicConfig(level=logging.INFO)
#設定語音檔案存入路徑(可覆寫,解記憶體)
def save_audio():
pass
#定義訊息回呼函式
def msg_callback(message):
queue_message.put(message)
#退出事件回呼
def on_exit(wx_id):
print('已退出:{}'.format(wx_id))
#訊息處理,分流
def thread_handle_message(wx,wx_id,ws_t,ws_a):
while True:
message=queue_message.get()
print(message)
tp=message['msg_type']
sd=message['sender']
content=message['content']#訊息的內容
id=message['wx_id']
try: #首先判斷是否為群訊息還是個人訊息
if sd==None:
if tp==1:
#文本訊息0
infor=ws_t.received_message(content)
wx.send_text(wx_id.id,infor)
elif tp==3:
#直接回答暫時不能回答
infor='我暫時還未被開發視覺系統哦'
wx.send_text(wx_id,id,infor)
elif tp==34:
#語音訊息
pass
else:
if tp==1:
infor=ws_t.received_message(content)
wx.send_text_and_at_number(wx_id,id,msg=infor)
elif tp==3:
#直接回答暫時不能回答
infor='小汪很菜,未開發出視覺系統'
wx.send_text_and_at_number(wx_id,id,msg=infor)
elif tp==34:
#利用科大訊飛進行語音轉換
#然后同步三
pass
except:
pass
if __name__=='__main__':
#創建機器人類,一個文字類,一個語音類
ws_t=wsapiclient(url=get_conparam(0),protocols=['chat'],
msgs=msgs,flag=0)
ws_a=wsapiclient(url=get_conparam(1),protocols=['chat'],
msgs=msgs,flag=1)
ws_t.connect()
ws_t.run_forever()
ws_a.connect()
ws_a.run_forever()
#同時構造長連接,實作不斷開
#定義微信介面類
wx=WeChatPYApi(msg_callback=msg_callback,exit_callback=on_exit,logger=logging)
wx.start_wx()#驅動微信
while not wx.get_self_info():
time.sleep(5)
print('login success')
#登錄成功后,進行后續操作
#獲取登錄資訊
dict_1=wx.get_self_info()
self_wx=dict_1['wx_id']
threading.Thread(target=thread_handle_message,args=(wx,self_wx,ws_a,ws_t)).start()
#進行資訊的收發
在demo中運行過一次,應該是沒有問題的,如果有,那就是你的問題了哈,
3.后期總結
1.這是個知識付費的時代,想要白嫖就得花費時間成本去找,
2.不要隨意使用小眾官方檔案!!!描述及其不走心,很多東西需要自己去嘗試才能找到解決方法,及其浪費時間!為了讓你付費享受就將回傳訊息進行機密無法決議(可惡啊),
3.也學到了很多東西,比如將Web與程式的結合(雖然之前的爬蟲與自動化也類似,但完全自學的感覺不一樣嘛),對資訊的檢索以及專案的分工,享受享受,
4.不要口嗨,不要口嗨,說自己兩天就能完成任務!!!
4.后期可能的改進
我發現AIUI不僅有Websocket的介面,還有SDK的接入,后期可能會發布一個SDK接入的實體,
同時會將專案的漏洞以及功能更加完善,不過很有可能是擺爛丟專案
等專案最終完成會將工程上傳github,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/305415.html
標籤:其他
上一篇:打開我的收藏夾 --TCP篇


