Python微信庫:itchat ——實現微信自動回覆
我一個同學向我表示人類的本質是復讀機,就一直重複我的話,然後我就一”怒“之下搜了一下微信自動回覆機器人,然後發現了神奇的itchat庫,利用這個庫可以很簡單實現自動回覆的功能
開始之前,感覺有必要先介紹一下itchat的註冊訊息型別
- itchat要註冊訊息型別,比如註冊了TEXT(itchat.content.text),就會接收文字訊息,其他訊息不會觸發函式。訊息型別見庫中的content.py檔案
- 訊息型別判斷,msg[‘Type’]
- 訊息發起者,msg[‘FromUserName’]
- 訊息接收者,msg[‘ToUserName’]
- 文字訊息,msg[‘Content’]
- 檔名字,msg[‘FileName’],注:如果是自帶的表情就會顯示錶情
- 傳送檔案時,檔名字應該是unicode編碼(這是python內部預設的編碼風格)
傳送其他訊息
- 給自己傳送訊息只需要發出訊息,不指定傳送者,預設發給自己(登陸者) itchat.send_msg(‘nice to meet you’)
- 傳送圖片,ToUser不指定時發給自己 itchat.send_image(ImageName.decode(‘utf-8’),ToUser) # 傳送圖片
- 傳送視訊 itchat.send_video(VideoName.decode(‘utf-8’),ToUser) # 傳送圖片
- 傳送檔案 itchat.send_file(path.decode(‘utf-8’)) # 圖片(檔案)
我先放一下我執行成功的程式碼吧(我隨機生成了三個機器人)
# -*- coding=utf-8 -*- import requests import itchat import random KEY = '04f44290d4cf462aae8ac563ea7aac16' def get_response(msg): apiUrl = 'http://www.tuling123.com/openapi/api' data = { 'key': KEY, 'info': msg, 'userid': 'wechat-robot', } try: r = requests.post(apiUrl, data=data).json() return r.get('text') except: return @itchat.msg_register(itchat.content.TEXT) def tuling_reply(msg): defaultReply = 'I received: ' + msg['Text'] robots = ['——By1', '——By2', '——By3'] reply = get_response(msg['Text'])+random.choice(robots) return reply or defaultReply itchat.auto_login(hotReload=True) # itchat.auto_login(enableCmdQR=True)這個只能生成一行行二維碼,不能生成圖片 itchat.run()
1、start
最簡單的回覆
通過如下程式碼,可以完成回覆所有文字資訊(包括群聊)。
import itchat
from itchat.content import TEXT
@itchat.msg_register
def simply_reply(msg):
if msg['Type'] == TEXT:
return 'I received: %s' % msg['Content']
itchat.auto_login()
itchat.run()
常用訊息的配置
itchat支援所有的訊息型別與群聊,下面的示例中演示了對於這些訊息型別簡單的配置。
import itchat
from itchat.content import *
@itchat.msg_register([TEXT,MAP,CARD,NOTE,SHARING])
def text_reply(msg):
itchat.send('%s:%s'%(msg['Type'],msg['Text']),msg['FromeUserName'])
# 以下四類的訊息的Text鍵下存放了用於下載訊息內容的方法,傳入檔案地址即可
@itchat.msg_register([PICTURE, RECORDING, ATTACHMENT, VIDEO])
def download_files(msg):
msg['Text'](msg['FileName'])
return '@%[email protected]%s' % ({'Picture':'img','Video':'vid'}.get(msg['Type'], 'fil'), msg['FileName'])
# 收到好友邀請自動新增好友
@itchat.msg_register(FRIENDS)
def add_friend(msg):
itchat.add_friend(**msg['Text']) # 該操作會自動將新好友的訊息錄入,不需要過載通訊錄
itchat.send_msg('Nice to meet you!', msg['RecommendInfo']['UserName'])
# 在註冊時增加isGroupChat=True將判定為群聊回覆
@itchat.msg_register(TEXT, isGroupChat = True)
def groupchat_reply(msg):
if msg['isAt']:
itchat.send(u'@%s\u2005I received: %s' % (msg['ActualNickName'], msg['Content']), msg['FromUserName'])
itchat.auto_login(True)
itchat.run()
當然這裡不需要深究為什麼這些東西可以這麼寫,我在這裡放出了示例程式只是為了給你一個該sdk相關程式碼大概樣子的概念。
有了大概的模式的瞭解之後我們就可以進入下一部分的介紹。
2、login
在上一部分中你看到了基本的註冊與登陸,而顯然登陸使用的是itchat提供了auto_login方法,呼叫即可完成登入。
一般而言,我們都會在完成訊息的註冊後登陸。
當然這裡需要特別強調的是三點,分別是短時間關閉重連、命令列二維碼與自定義登陸內容。 itchat提供了登陸狀態暫存,關閉程式後一定時間內不需要掃碼即可登入。 為了方便在無圖形介面使用itchat,程式內建了命令列二維碼的顯示。 * 如果你需要就登入狀態就一些修改(例如更改提示語、二維碼出現後郵件傳送等)。
**0x01-1 短時間關閉程式後重連**
這樣即使程式關閉,一定時間內重新開啟也可以不用重新掃碼。
最簡單的用法就是給 auto_login
方法傳入值為真的 hotReload
。
該方法會生成一個靜態檔案 itchat.pkl
,用於儲存登陸的狀態。
import itchat
from itchat.content import TEXT
@itchat.msg_register(TEXT)
def simple_reply(msg):
print(msg['Text'])
itchat.auto_login(hotReload = True)
itchat.run()
itchat.dump_login_status()
通過設定statusStorageDir可以將靜態檔案指定為其他的值。
這一內建選項其實就相當於使用了以下兩個函式的這一段程式:
import itchat
from itchat.content import TEXT
if itchat.load_login_status():
@itchat.msg_register(TEXT)
def simple_reply(msg):
print(msg['Text'])
itchat.run()
itchat.dump_login_status()
else:
itchat.auto_login()
itchat.dump_login_status()
print('Config stored, so exit.')
其中load_login_status與dump_login_status分別對應讀取與匯出設定。
通過設定傳入的fileDir的值可以設定匯入匯出的檔案。
**0x01-2 命令列二維碼顯示**
通過以下命令可以在登陸的時候使用命令列顯示二維碼:
itchat.auto_login(enableCmQR=True)
部分系統可能字幅寬度有出入,可以通過將enableCmdQR賦值為特定的倍數進行調整:
# 如部分的linux系統,塊字元的寬度為一個字元(正常應為兩字元),故賦值為2
itchat.auto_login(enableCmdQR=2)
預設控制檯背景色為暗色(黑色),若背景色為淺色(白色),可以將enableCmdQR賦值為負值:
itchat.auto_login(enableCmdQR=-1)
**0x01-2 自定義登入過程**
如果需要控制登入的過程,可以閱讀下面的內容。
同時itchat也提供了登陸所需的每一步的方法,登陸的過程按順序為: 獲取二維碼uuid->獲取二維碼->判斷是否已經登陸成功->獲取初始化資料->更新微信相關資訊(通訊錄、手機登陸狀態)->迴圈掃描新資訊(開啟心跳)
獲取二維碼uuid
獲取生成二維碼所需的uuid,並返回。
- 方法名稱:
get_QRuuid
- 所需值:無
- 返回值:成功->uuid,失敗->None
獲取二維碼
根據uuid獲取二維碼並開啟,返回是否成功。
- 方法名稱:
get_QR
- 所需值:uuid
- 返回值:成功->True,失敗->False
判斷是否已經登陸成功
判斷是否已經登陸成功,返回掃描的狀態碼。
- 方法名稱:
check_login
- 所需值:uuid
- 返回值:登陸成功->'200',已掃描二維碼->'201',二維碼失效->'408',未獲取到資訊->'0'
獲取初始化資料
獲取微信使用者資訊以及心跳所需要的資料。
- 方法名稱:
web_init
- 所需值:無
- 返回值:儲存登入微信使用者資訊的字典
獲取微信通訊錄
獲取微信的所有好友資訊並更新。
- 方法名稱:
get_contract
- 所需值:無
- 返回值:儲存好友資訊的列表
更新微信手機登陸狀態
在手機上顯示登入狀態。
- 方法名稱:
show_mobile_login
- 所需值:無
- 返回值:無
迴圈掃描新資訊(開啟心跳)
迴圈掃描是否有新的訊息,開啟心跳包。
- 方法名稱:
start_receiving
- 所需值:無
- 返回值:無
EG:
一個登入例子:
import itchat, time, sys
def output_info(msg):
print('[INFO] %s' % msg)
def open_QR():
for get_count in range(10):
output_info('Getting uuid')
uuid = itchat.get_QRuuid()
while uuid is None: uuid = itchat.get_QRuuid();time.sleep(1)
output_info('Getting QR Code')
if itchat.get_QR(uuid): break
elif get_count >= 9:
output_info('Failed to get QR Code, please restart the program')
sys.exit()
output_info('Please scan the QR Code')
return uuid
uuid = open_QR()
waitForConfirm = False
while 1:
status = itchat.check_login(uuid)
if status == '200':
break
elif status == '201':
if waitForConfirm:
output_info('Please press confirm')
waitForConfirm = True
elif status == '408':
output_info('Reloading QR Code')
uuid = open_QR()
waitForConfirm = False
userInfo = itchat.web_init()
itchat.show_mobile_login()
itchat.get_contract()
output_info('Login successfully as %s'%userInfo['NickName'])
itchat.start_receiving()
# Start auto-replying
@itchat.msg_register
def simple_reply(msg):
if msg['Type'] == 'Text':
return 'I received: %s' % msg['Content']
itchat.run()
3、register
註冊訊息方法
itchat將根據接收到的訊息型別尋找對應的已經註冊的方法。 如果一個訊息型別沒有對應的註冊方法,該訊息將會被捨棄。 在執行過程中也可以動態註冊方法,註冊方式與結果不同
註冊
你可以通過兩種方式註冊訊息方法
import itchat
from itchat.content import *
#不帶引數註冊,所有訊息型別都將呼叫該方法(包括群訊息)
@itchat.msg_register
def simple_reply(msg):
if msg['Type'] == 'Text':
return 'I received: %s' % msg['Text']
#帶引數註冊,該類訊息型別將呼叫該方法
@itchat.msg_register([TEXT, MAP, CARD, NOTE, SHARING])
def text_reply(msg):
itchat.send('%s: %s' % (msg['Type'], msg['Text']), msg['FromUserName'])
訊息型別:在這裡在敘述一遍,感覺我們處理微信訊息的時候麻煩一點的應該也就是分型別回覆了
向註冊方法傳入的msg包含微信返回的字典的所有內容。
本api增加Text、Type(也就是引數)鍵值,方便操作。
itchat.content中包含所有的訊息型別引數,內容如下表所示:
引數 | 型別 | Text鍵值 |
TEXT | 文字 | 文字內容 |
MAP | 地圖 | 位置文字 |
CARD | 名片 | 推薦人字典 |
NOTE | 通知 | 通知文字 |
SHARING | 分享 | 分享名稱 |
PICTURE | 圖片/表情 | 下載方法 |
RECODING | 語音 | 下載方法 |
ATTACHMENT | 附件 | 下載方法 |
VIDEO | 小視訊 | 下載方法 |
FRIENDS | 好友邀請 | 新增好友所需引數 |
Useless | 無用資訊 | ‘UselessMsg' |
比如你需要儲存傳送給你的附件:
@itchat.msg_register(ATTACHMENT)
def download_files(msg):
msg['Text'](msg['FileName'])
值得注意的是,群訊息增加了三個鍵值: isAt: 判斷是否@本號 ActualNickName: 實際NickName * Content: 實際Content
可以通過本程式測試:
import itchat
from itchat.content import TEXT
@itchat.msg_register(TEXT, isGroupChat = True)
def text_reply(msg):
print(msg['isAt']
print(msg['ActualNickName'])
print(msg['Content'])
itchat.auto_login()
itchat.run()
註冊訊息的優先順序
優先順序分別為:後註冊訊息先於先註冊訊息,帶引數訊息先於不帶引數訊息。
以下面的兩個程式為例:
import itchat
from itchat.content import *
itchat.auto_login()
@itchat.msg_register(TEXT)
def text_reply(msg):
return 'This is the old register'
@itchat.msg_register(TEXT)
def text_reply(msg):
return 'This is a new one'
itchat.run()
在私聊傳送文字時將會回覆This is a new one。
import itchat
from itchat.content import*
itchat.auto_login()
@itchat.msg_register
def general_reply(msg):
return 'I received a %s' % msg['Type']
@itchat.msg_register(TEXT)
def text_reply(msg):
return 'You said to me one to one: %s' % msg['Text']
itchat.run()
僅在私聊傳送文字時將會回覆You said to me one to one,其餘情況將會回覆I received a ...。
動態註冊資訊
動態註冊時可以選擇將 itchat.run()
放入另一執行緒或使用 configured_reply()
方法處理訊息。
兩種方法分別是:
# 使用另一執行緒,但注意不要讓程式執行終止
import thread
thread.start_new_thread(itchat.run, ())
# 使用configured_reply方法
while 1:
itchat.configured_reply()
# some other functions
time.sleep(1)
以下給出一個動態註冊的例子
#coding=utf8
import thread
import itchat
from itchat.content import *
replyToGroupChat = True
functionStatus = False
def change_function():
if replyToGroupChat != functionStatus:
if replyToGroupChat:
@itchat.msg_register(TEXT, isGroupChat = True)
def group_text_reply(msg):
if u'關閉' in msg['Text']:
replyToGroupChat = False
return u'已關閉'
elif u'開啟' in msg['Text']:
return u'已經在執行'
return u'輸入"關閉"或者"開啟"測試功能'
else:
@itchat.msg_register(TEXT, isGroupChat = True)
def group_text_reply(msg):
if u'開啟' in msg['Text']:
replyToGroupChat = True
return u'重新開啟成功'
functionStatus = replyToGroupChat
thread.start_new_thread(itchat.run, ())
while 1:
change_function()
time.sleep(.1)
4、reply
回覆
itchat提供五種回覆方法,建議直接使用send方法。
send方法
-
方法:
send(msg='Text Message', toUserName=None)
- 所需值:
1.msg:訊息內容
2.'@[email protected]檔案地址'將會被識別為傳送檔案,'@[email protected]圖片地址'將會被識別為傳送圖片,'@[email protected]視訊地址'將會被識別為小視訊
3.toUserName:傳送物件,如果留空將會發送給自己
- 返回值:傳送成功->True, 失敗->False
import itchat itchat.aauto_login() itchat.send('Hello world!') # 請確保該程式目錄下存在:gz.gif以及xlsx.xlsx itchat.send('@[email protected]%s' % 'gz.gif') itchat.send('@[email protected]%s' % 'xlsx.xlsx') itchat.send('@[email protected]%s' % 'demo.mp4')
send_msg方法
-
方法:
send_msg(msg='Text Message', toUserName=None)
-
所需值:
msg:訊息內容 toUserName:傳送物件,如果留空將會發送給自己
-
返回值:傳送成功->True, 失敗->False
-
程式示例:
import itchat itchat.auto_login() itchat.send_msg('Hello world')
send_file方法
-
方法:
send_file(fileDir, toUserName=None)
-
所需值:
fileDir:檔案路徑(不存在該檔案時將列印無此檔案的提醒) toUserName:傳送物件,如果留空將會發送給自己
-
返回值:傳送成功->True, 失敗->False
-
程式示例:
import itchat itchat.auto_login() #請確保該程式目錄下存在:xlsx.xlsx itchat.send_file('xlsx.xlsx')
send_img方法
-
方法:
send_img(fileDir, toUserName=None)
-
所需值:
fileDir:檔案路徑(不存在該檔案時將列印無此檔案的提醒) toUserName:傳送物件,如果留空將會發送給自己
-
返回值:傳送成功->True, 失敗->False
-
程式示例:
import itchat itchat.auto_login() # 請確保該程式目錄下存在:gz.gif itchat.send_img('gz.gif')
send_video方法
-
方法:
send_video(fileDir, toUserName=None)
- 所需值:
fileDir:檔案路徑(不存在該檔案時將列印無此檔案的提醒)
toUserName:傳送物件,如果留空將會發送給自己
- 返回值:傳送成功->True, 失敗->False
需要保證傳送的視訊為一個實質的mp4檔案
import itchat
itchat.auto_login()
#請確保該程式目錄下存在:demo.mp4
itchat.send_file('demo.mp4')
5、Memmber stuff
在使用個人微信的過程當中主要有三種賬號需要獲取,分別為: 好友 公眾號 * 群聊
itchat為這三種賬號都提供了整體獲取方法與搜尋方法。
而群聊多出獲取使用者列表方法以及建立群聊、增加、刪除使用者的方法。
這裡我們分這三種分別介紹如何使用。
好友
好友的獲取方法為 get_friends
,將會返回完整的好友列表。 其中每個好友為一個字典 列表的第一項為本人的賬號資訊 * 傳入update鍵為True將可以更新好友列表並返回
好友的搜尋方法為 search_friends
,有四種搜尋方式: 1. 僅獲取自己的使用者資訊 2. 獲取特定 UserName
的使用者資訊 3. 獲取備註、微訊號、暱稱中的任何一項等於 name
鍵值的使用者 4. 獲取備註、微訊號、暱稱分別等於相應鍵值的使用者
其中三、四項可以一同使用,下面是示例程式:
# 獲取自己的使用者資訊,返回自己的屬性字典
itchat.search_friends()
# 獲取特定UserName的使用者資訊
itchat.search_friends(userName='@abcdefg1234567')
# 獲取任何一項等於name鍵值的使用者
itchat.search_friends(name='littlecodersh')
# 獲取分別對應相應鍵值的使用者
itchat.search_friends(wechatAccount='littlecodersh')
# 三、四項功能可以一同使用
itchat.search_friends(name='LittleCoder機器人', wechatAccount='littlecodersh')
公眾號
公眾號的獲取方法為 get_mps
,將會返回完整的公眾號列表。 其中每個公眾號為一個字典 傳入update鍵為True將可以更新公眾號列表並返回
公眾號的搜尋方法為 search_mps
,有兩種搜尋方法: 1. 獲取特定 UserName
的公眾號 2. 獲取名字中含有特定字元的公眾號
如果兩項都做了特定,將會僅返回特定 UserName
的公眾號,下面是示例程式:
# 獲取特定UserName的公眾號,返回值為一個字典
itchat.search_mps(userName='@abcdefg1234567')
# 獲取名字中含有特定字元的公眾號,返回值為一個字典的列表
itcaht.search_mps(name='LittleCoder')
# 以下方法相當於僅特定了UserName
itchat.search_mps(userName='@abcdefg1234567', name='LittleCoder')
群聊
群聊的獲取方法為 get_chatrooms
,將會返回完整的群聊列表。 其中每個群聊為一個字典 傳入update鍵為True將可以更新群聊列表並返回
群聊的搜尋方法為 search_chatrooms
,有兩種搜尋方法: 1. 獲取特定UserName的群聊 2. 獲取名字中含有特定字元的群聊
如果兩項都做了特定,將會僅返回特定UserName的群聊,下面是示例程式:
# 獲取特定UserName的群聊,返回值為一個字典
itchat.search_chatrooms(userName='@abcdefg1234567')
# 獲取名字中含有特定字元的群聊,返回值為一個字典的列表
itcaht.search_chatrooms(name='LittleCoder')
# 以下方法相當於僅特定了UserName
itchat.search_chatrooms(userName='@abcdefg1234567', name='LittleCoder')
群聊使用者列表的獲取方法為 update_chatroom
。 群聊在首次獲取中不會獲取群聊的使用者列表,所以需要呼叫該命令才能獲取群聊的成員 該方法需要傳入群聊的UserName,返回特定群聊的使用者列表
memberList = itchat.update_chatroom('@abcdefg1234567')
建立群聊、增加、刪除群聊使用者的方法如下所示: 由於之前通過群聊檢測是否被好友拉黑的程式,目前這三個方法都被嚴格限制了使用頻率 刪除群聊需要本賬號為群管理員,否則會失敗
memberList = itchat.get_friends()[1:]
# 建立群聊,topic鍵值為群聊名
chatroomUserName = itchat.create_chatroom(memberList, 'test chatroom')
# 刪除群聊內的使用者
itchat.delete_member_from_chatroom(chatroomUserName, memberList[0])
# 增加使用者進入群聊
itchat.add_member_into_chatroom(chatroomUserName, memberList[0])
6、QAQ
Q: 為什麼我在設定了itchat.auto_login()的enableCmdQR為True後還是沒有辦法在命令列顯示二維碼?
A: 這是由於沒有安裝可選的包 pillow
,可以使用右邊的命令安裝: pip install pillow
7、eg
def signin():
# 查詢公眾號,進行簽到
user = itchat.search_mps(name='Nulll.me')
UserName = user[0]['UserName']
itchat.send(msg=u'3', toUserName=UserName)
itchat.dump_login_status()
pickleDumps('flag', localDay) # 如果執行成功寫入標緻檔案
exit()
if __name__ == '__main__':
# 如果不是在登陸狀態,就迴圈登陸
while not itchat.load_login_status():
sendMail()
itchat.auto_login(hotReload=True)
itchat.dump_login_status()
signin() # 簽到
time.sleep(3600)
signin() # 簽到
好了,大致內容就是這些了,玩得愉快