實現的功能 只要有人給你發了表情包,不管是群聊還是個人發的,都將它保存到本地。也許某天鬥圖的時候就能用到,不過即使有了表情包,還需要一個檢索功能,不然這一張一張看也太費眼睛了。 檢索表情包 檢索表情包的功能實現比較麻煩,至少需要兩個模型:ocr和圖片描述生成,如果更複雜點的話還需要分詞演算法、資料庫等 ...
實現的功能
只要有人給你發了表情包,不管是群聊還是個人發的,都將它保存到本地。也許某天鬥圖的時候就能用到,不過即使有了表情包,還需要一個檢索功能,不然這一張一張看也太費眼睛了。
檢索表情包
檢索表情包的功能實現比較麻煩,至少需要兩個模型:ocr和圖片描述生成,如果更複雜點的話還需要分詞演算法、資料庫等。
需要ocr應該很容易理解,表情包裡面包含文字信息,使用ocr將文字提取出來,這個文字基本就可以作為檢索的信息了。
如果表情沒有文字,那隻能使用一些模型,為圖片生成一個簡單的描述,然後將這個描述作為檢索的信息。
搜了一下目前開源的模型裡面沒看到比較合適的。後面如果遇到了再做一個簡單的表情包檢索程式。
開始實現
效果圖
github代碼
https://github.com/kanadeblisst00/WeChat-PyRobot
http://www.pygrower.cn:21180/kanadeblisst/WeChat-PyRobot
實現原理
使用Python來監聽微信消息,如果收到表情包消息就提取裡面的鏈接並下載,因為表情包xml消息里有一個未加密的鏈接。
監聽消息的原理和代碼可以看之前的一篇文章: 【Python微信機器人】第八篇: 實戰32位和64位接收消息和消息防撤回
代碼在上篇文章的基礎上做瞭如下優化:
- 使用隊列存儲監聽到的消息
- 支持載入消息插件來處理消息
- 支持註入後就自動監聽消息
待實現插件列表
- 監聽群聊中的群二維碼
- 監聽並實時採集關註的公眾號文章
- 自動下載並解密聊天中的圖片
- chatgpt自動回覆
- 群消息關鍵詞提醒
- 消息保存到資料庫,如sqlite、postgresql等
- 自動接收轉賬
- 監聽收款信息對接發卡平臺,目前可以用v免簽+獨角數卡
開始監聽並下載表情包
準備工作
- 安裝支持的版本微信(目前只寫了
3.9.8.12
和3.9.8.15
的代碼) - 安裝32位或64位Python(取決於你安裝的微信是32位還是64位),Python版本需大於等於3.8
pip install wechat_pyrobot==1.1.1
如果國內源還沒有同步最新版本,可以指定-i https://pypi.org/simple/
選項使用pip官方庫
開始監聽消息
先啟動並登錄微信,隨便創建一個文件夾,然後創建一個文件main.py
(名稱隨意)寫入以下代碼:
from py_process_hooker import inject_python_and_monitor_dir
from wechat_pyrobot import get_on_startup
from wechat_pyrobot.msg_plugins import PrintMsg, DownLoadEmotion
if __name__ == "__main__":
process_name = "WeChat.exe"
open_console = True
on_startup = get_on_startup(msg_plugins=[PrintMsg, DownLoadEmotion])
inject_python_and_monitor_dir(process_name, __file__, open_console=open_console, on_startup=on_startup)
使用Python運行這段代碼,就會將Python註入到微信,並且開始監聽微信收到的消息,然後將監聽到的消息依次傳遞給msg_plugins指定的插件列表。
DownLoadEmotion插件就是用來下載表情包的,裡面的代碼很簡單:
class DownLoadEmotion(MsgPluginTemplate):
def __init__(self, **kwargs) -> None:
self.name = os.path.basename(__file__)[:-3]
super().__init__(**kwargs)
self.emotion_save_path = os.path.join(kwargs["pwd"], "emotion")
os.makedirs(self.emotion_save_path, exist_ok=True)
def deal_msg(self, msg_dict):
if msg_dict["msg_type"] != 0x2F:
return
xml = msg_dict["content"]
root = ET.fromstring(xml)
datas = dict(root.find('.//emoji').items())
cdnurl = datas["cdnurl"].replace('&', '&')
filename = msg_dict["file_path"]
if not filename:
filename = msg_dict["msgid"]
save_path = f"{self.emotion_save_path}{os.sep}{filename}.gif"
with open(save_path, 'wb') as f:
f.write(self.download_file(cdnurl))
def download_file(self, url, retry=0):
if retry > 2:
return
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.183"
}
try:
resp = requests.get(url, headers=headers, timeout=6)
except:
traceback.print_exc()
time.sleep(2)
return self.download_file(url, retry+1)
return resp.content
先判斷一下消息類型是不是0x2F
,也就是表情包的消息類型,然後提取xml數據里的cdnurl,用requests下載下來保存到本地
編寫自己的插件
可以先參考目前已有的插件例子,代碼在wechat_pyrobot/msg_plugins
, 在github或者pip本地目錄都可以看到
編寫一個消息保存到文件的插件
插件需要繼承MsgPluginTemplate,然後實現deal_msg方法,方法只有一個參數:字典類型的消息
my_msg_plugin/save_to_file.py
import os
import json
from wechat_pyrobot.plugin_class import MsgPluginTemplate
class SaveToFile(MsgPluginTemplate):
def __init__(self, **kwargs) -> None:
self.name = os.path.basename(__file__)[:-3]
super().__init__(**kwargs)
# kwargs["pwd"]是main.py所在路徑
self.msg_save_path = os.path.join(kwargs["pwd"], "msg_save_path")
os.makedirs(self.msg_save_path, exist_ok=True)
def deal_msg(self, msg_dict):
path = os.path.join(self.msg_save_path, f'{msg_dict["msgid"]}.json')
with open(path, 'w', encoding='utf-8') as f:
f.write(json.dumps(msg_dict))
然後在註入的代碼(main.py
)裡加載它,需要重新啟動並註入微信
from py_process_hooker import inject_python_and_monitor_dir
from wechat_pyrobot import get_on_startup
from wechat_pyrobot.msg_plugins import PrintMsg, DownLoadEmotion
from my_msg_plugin.save_to_file import SaveToFile
if __name__ == "__main__":
process_name = "WeChat.exe"
open_console = True
on_startup = get_on_startup(msg_plugins=[PrintMsg, DownLoadEmotion, SaveToFile])
inject_python_and_monitor_dir(process_name, __file__, open_console=open_console, on_startup=on_startup)
這樣收到的消息都會保存到文件,當然這個只是示例。實際應該按時間來分類文件,或者保存到資料庫中。
插件列表是有順序的,在執行時會依次執行,如果之前的插件修改了消息字典,那麼之後的插件得到的消息字典就是修改後的
本文由博客一文多發平臺 OpenWrite 發佈!