主頁 > 軟體設計 > 基于python以及AIUI WebSocket,WeChatPYAPI實作的微信聊天機器人

基于python以及AIUI WebSocket,WeChatPYAPI實作的微信聊天機器人

2021-10-05 08:03:07 軟體設計

基于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 + "&param=" + 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篇

下一篇:通過wireshark抓取telnet登陸密碼

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more