從零開始實現微信機器人


從零開始實現微信機器人

 

閱讀目錄

安裝wxpy

wxpy 登陸

wxpy 好友與聊天群

wxpy 消息處理

wxpy 圖靈機器人

wechat_sender 

 

 

安裝wxpy

安裝wxpy非常簡單,如果你擁有pip,請直接按照Github中的方法安裝:

從 PYPI 官方源下載安裝 (在國內可能比較慢或不穩定):

pip install -U wxpy

從豆瓣 PYPI 鏡像源下載安裝 (推薦國內用戶選用):

pip install -U wxpy -i "https://pypi.doubanio.com/simple/"
 

 wxpy 登陸

  wxpy 使用起來非常簡單,我們只需要創建一個bot 對象,程序運行后,會彈出二維碼,掃描二維碼后顯示登陸成功。

  下述代碼在登陸完成后,會向我們的文件傳輸助手發送一個“hello world!”。(每個程序都需要一個hello world)。

from wxpy import *

bot = Bot()

bot.file_helper.send('hello world!')

print("ending")

關於Bot()對象的相關參數說明,我們可以在源碼中的注釋中看到:

"""
:param cache_path:
    * 設置當前會話的緩存路徑,並開啟緩存功能;為 `None` (默認) 則不開啟緩存功能。
    * 開啟緩存后可在短時間內避免重復掃碼,緩存失效時會重新要求登陸。
    * 設為 `True` 時,使用默認的緩存路徑 'wxpy.pkl'。
:param console_qr:
    * 在終端中顯示登陸二維碼,需要安裝 pillow 模塊 (`pip3 install pillow`)。
    * 可為整數(int),表示二維碼單元格的寬度,通常為 2 (當被設為 `True` 時,也將在內部當作 2)。
    * 也可為負數,表示以反色顯示二維碼,適用於淺底深字的命令行界面。
    * 例如: 在大部分 Linux 系統中可設為 `True` 或 2,而在 macOS Terminal 的默認白底配色中,應設為 -2。
:param qr_path: 保存二維碼的路徑
:param qr_callback: 獲得二維碼后的回調,可以用來定義二維碼的處理方式,接收參數: uuid, status, qrcode
:param login_callback: 登陸成功后的回調,若不指定,將進行清屏操作,並刪除二維碼文件
:param logout_callback: 登出時的回調
"""

這里介紹一下三個主要使用到的參數:

cache_path: 在開發過程中可以設置為True 避免每次登陸都需要重新掃描,具有緩存的作用。
qr_path:用於保存二維碼生成圖片,主要解決服務器圖片展示不方便的問題。
console_qr:有些情況下,可能不能通過終端打開圖片(例如部署在服務器上時),我們可以通過參數選擇在終端內顯示二維碼。

 wxpy 好友與聊天群

如代碼所示,我們可以通過Bot.friends 以及Bot.groups 來獲取到所有的好友以及聊天群,這里需要注意的是,聊天群需要保存到通訊錄中,不然可能會出現找不到聊天群的情況。

    在搜索方法中,可以提供的參數有:姓名,city,province,sex 等相關變量。

    關於好友的詳細API文檔,可以參考---》 微信好友API

from wxpy import *

bot = Bot()

# 獲取所有好友
friends = bot.friends()

# 遍歷輸出好友名稱
for friend in friends:
    print(friend)

# 找到好友
friend = bot.friends.search('被單')[0]
print(friend)
friend.send("hello world!")

# 獲取所有聊天群
groups = bot.groups()

for group in groups:
    print(group)

# 找到目標群
group = groups.search("409")[0]

group.send("hello world!")

 

wxpy 消息處理

接下來主要介紹一下用戶發送消息的類型,目前wxpy 支持發送文本,圖片,視頻以及文件。主要的發送方式如代碼所示:

from wxpy import *

bot = Bot()
# 獲取好友
my_friend = bot.friends().search('被單')[0]

# 搜索信息
messages = bot.messages.search(keywords='測試', sender=bot.self)

for message in messages:
    print(message)

# 發送文本
my_friend.send('Hello, WeChat!')
# 發送圖片
my_friend.send_image('my_picture.png')
# 發送視頻
my_friend.send_video('my_video.mov')
# 發送文件
my_friend.send_file('my_file.zip')
# 以動態的方式發送圖片
my_friend.send('@img@my_picture.png')

# 發送公眾號
my_friend.send_raw_msg(
    # 名片的原始消息類型
    raw_type=42,
    # 注意 `username` 在這里應為微信 ID,且被發送的名片必須為自己的好友
    raw_content='<msg username="wxpy_bot" nickname="wxpy 機器人"/>'
)


# 消息接收監聽器
@bot.register()
def print_others(msg):
    # 輸出監聽到的消息
    print(msg)
    # 回復消息
    msg.reply("hello world")


embed()
程序示例

這里比較重要的就是關於 @bot.register() 的使用,該注釋主要用於注冊消息接收器,我們可以根據特定的需求,配置不一樣的消息接收器。

Bot.register(chats=None, msg_types=None, except_self=True, run_async=True, enabled=True)

詳情可以查看源碼中的介紹

關於消息處理API,讀者可以在該地址下查看詳細的配置,這里不做過多的描述。

代碼中有使用到:embed() 這個方法, 主要用於阻塞進程,避免由於程序運行結束導致無法接收消息。

# 獲取所有類型的消息(好友消息、群聊、公眾號,不包括任何自己發送的消息)
# 並將獲得的消息打印到控制台
@bot.register()
def print_others(msg):
    print(msg)

同時wxpy也可以給注冊消息的類型加上限制:

# 回復 my_friend 發送的消息
@bot.register(my_friend)
def reply_my_friend(msg):
    return 'received: {} ({})'.format(msg.text, msg.type)

# 回復發送給自己的消息,可以使用這個方法來進行測試機器人而不影響到他人
@bot.register(bot.self, except_self=False)
def reply_self(msg):
    return 'received: {} ({})'.format(msg.text, msg.type)

# 打印出所有群聊中@自己的文本消息,並自動回復相同內容
# 這條注冊消息是我們構建群聊機器人的基礎
@bot.register(Group, TEXT)
def print_group_msg(msg):
    if msg.is_at:
        print(msg)
        msg.reply(meg.text)

當然僅僅寫以上內容,會導致你的程序主程序運行結束自然退出。wxpy給出了embed()方法,在程序末尾(或其他你想要暫停調試的地方)加上embed()方法就可以讓程序保持運行,同時進入Python命令行。

# 進入 Python 命令行、讓程序保持運行
# 推薦使用
embed()

# 或者僅僅堵塞線程
# bot.join()

 

 

wxpy 圖靈機器人

前期准備

前往注冊圖靈機器人,增加一個機器人,並記錄機器人的APIKey。具體注冊方法可以前往圖靈API查看。

 

使用

1.首先,將圖靈API寫入程序中:

TULING_TOKEN = 'Your API Key'

2.然后,定義接口鏈接和需要傳輸的數據:

url_api = 'http://www.tuling123.com/openapi/api'
data = {
    'key'    : TULING_TOKEN,
    'info'   : msg.text, # 收到消息的文字內容
}

3.根據文檔,通過HTTP請求,我們將會得到一個json格式的文件。使用Requests包,我們可以簡單的獲得調用接口所返回的信息:

s = requests.post(url_api, data=json.dumps(data))
s =json.loads(s.text)

4.我們一般會得到一個字典內容,其中包括text和code兩項:text是圖靈機器人回復的文本,而code是返回的編號。詳細的返回數據格式也可以在圖靈API中看到,除了文字類還有新聞類、圖片類、鏈接類等返回類型。在這里我們以文字類為例,介紹如何處理:

if s['code'] == 100000:
        print s['text'] # 查看回復消息的內容,可省略
        msg.reply(s['text']) # 回復消息

如果需要回復其他類型的消息,也完全可以通過判斷code確定消息類型,再決定如何回復。這里給出我的回復方法供大家參考(也可以選擇不處理這一類內容):

if s['code'] == 200000: # 鏈接類:回復文字和鏈接
    msg.reply(s['text'] + s['url'])

5.wxpy給每個用戶定義了一個相對穩定的對象/用戶id,為puid,可以始終被獲取到並有唯一的穩定性(根據文檔),我們可以使用這個id來作為userid傳給圖靈機器人,以方便識別機器人或航班/列成信息的上下文。

bot.enable_puid() # puid 需要手動開啟,請將這句話寫在登陸登錄之后

這樣傳送給接口的數據也要同時修改為:

data = {
    'key'    : TULING_TOKEN,
    'info'   : msg.text, # 收到消息的文字內容
    'userid' : msg.member.puid, # 使用群聊中發送者的 puid 作為 userid 傳送給圖靈接口, 如果是私聊可以使用 msg.sender.puid
}

這樣做的好處是,圖靈機器人可以根據得userid來獲取上下文信息。例如你詢問『天氣』,它會回復『親愛的,悄悄地告訴我你在哪個城市?』。在這種情況下,如果你不使用userid參數,你再次回復城市,圖靈機器人也無法正確找到天氣;如果你使用了這一參數,且兩次回復使用的userid相同,圖靈機器人會為你回復你回復的城市的天氣情況,完成這一對話。

 

完整程序

# -*- coding: utf-8 -*-
from wxpy import *
import requests
import json
TULING_TOKEN = 'you api key'
bot = Bot()
bot.enable_puid() # puid 需要手動開啟
@bot.register()  # 這里沒有參數默認為回復全部
def group_msg(msg):
        url_api = 'http://www.tuling123.com/openapi/api'
        data = {
            'key': TULING_TOKEN,
            'info': msg.text,  # 收到消息的文字內容
            'userid': msg.sender.puid,
        }
        s = requests.post(url_api, data=json.dumps(data))
        s =json.loads(s.text)
        print(s ) # 打印所獲得的json查看如何使用
        if s['code'] == 100000:
            print(s['text'])  # 查看回復消息的內容,可省略
            msg.reply(s['text'])  # 回復消息
embed()

 

 

wechat_sender 

在熟悉了wxpy 的相關操作后,我們接下來介紹一下一個主要使用到的工具。由於wxpy 的設計,導致了一些業務操作並不好進行實現。因此我們在這里引入一個工具類:wechat_sender 。

首先我們需要像往常一樣進行微信登陸,然后使用 listen() 進行對我們的 bot() 對象進行監聽。

在這里我們可以看到了和上面代碼的區別,這里使用的是listen(),上面是使用embed()進行監聽。 我們再這里使用listen 進行監聽對象后,可以設置相應的配置。監聽默認設置的接收對象為self.file_helper,通過設置receivers 可以配置消息的接收者。

# login.py
from wxpy import *
from wechat_sender import *

bot = Bot()

friend = bot.friends().search('被單')[0]

listen(bot, token='test', receivers=[friend])
# sender.py  coding: utf-8
from wechat_sender import Sender

sender = Sender(token='test')

sender.send('hello world!')

在別的python 文件中,我們只需要創建一個Sender() 對象,然后調用Sender.send()方法,即可對我們設定好的消息接收者發送消息。

Sender()在創建的時候可以通過特定的參數設定,比如這里使用了 token 用於避免多個listen 導致sender 混淆。還可以在sender中設置receiver 從listen 中選取需要接收消息的對象。







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM