一. 引言
我們都知道微信提供了多種登入的方式包括手機端、電腦端以及web端。
web端的登入我們用Python程式完全可以模拟出來~~如果你不知道那也沒關系稍微了解下Python request session即可
而所謂的機器人實際上就是背景一個智能的程式類似“微軟小冰”“iPhone siri”。今天我們要用的是一個開放的機器人API“圖靈機器人”
下面就讓我們一步步分析如何通過模拟web端微信登入+“圖靈機器人” 實作一個微信機器人
二. 深入分析
1. web版微信不是用使用者名密碼而是用掃描二維碼登入如何實作的呢
讓我們登入https://wx.qq.com/檢視此時的網絡請求情況 如下圖所示
1). 實際上用戶端會先發送一個js get請求請求url為https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_=1469852355025
仔細分析這個請求會發現有已下幾個參數
appid: wx782c26e4c19acffb //這個值不變表示來自微信網頁版
redirect_uri: https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage //這個也是一個固定值
fun: new //固定值位new
lang: zh_CN //表示中文
_: 1469852355025 //13位時間戳
2).然後服務端傳回資料window.QRLogin.code = 200; window.QRLogin.uuid = "IatVataLfQ==";
2. 多重新整理幾次你會發現服務端的傳回值中window.QRLogin.uuid的值每次都在變化。
實際上uuid是服務端用來辨別一次登入的通信id

2. 當我們拿到uuid後就需要擷取二維碼繼續檢視目前的網絡請求
1). 用戶端繼續發送一個js get 請求url為https://login.weixin.qq.com/qrcode/IatVataLfQ==
仔細分析這個請求會發現qrcode後跟着的值就是從上一個請求拿到的uuid值
2). 當拿到二維碼之後還需用微信用戶端進行掃描god都有用戶端了為什麼還需用用web登入~~~~
3. ok拿出手機掃描螢幕的二維碼繼續檢視網絡請求
1). 當我們在APP上點選登入按鈕之後實際上用戶端是向服務端發送了一個js的get 請求url為https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=od5FW4ipFw==&tip=0&r=-979422099&_=1469857970642
仔細分析這個請求會發現有以下幾個參數
uuid: od5FW4ipFw== //從上面請求得到的資料
tip: 0 //表示等待使用者掃描确認
r: -979422099 //随機9位數字
_: 1469857970642 //13位時間戳
2). 這個請求傳回結果如下所示
window.code=200;
window.redirect_uri="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=AUyRV3zm5RBTWt-mEvvDz8oz@qrticket_0&uuid=od5FW4ipFw==&lang=zh_CN&scan=1469858238";
code=200表示的是成功redirect_uri表示需要我們繼續請求的url
4. 繼續上一個請求得到的redirect_uri
1). ok分析這個uri請求https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=AUyRV3zm5RBTWt-mEvvDz8oz@qrticket_0&uuid=od5FW4ipFw==&lang=zh_CN&scan=1469858238&fun=new&version=v2對應參數如下所示
uuid: 同前面
scan: 1469858238 //表示使用者掃描的時間戳10位
其它參數保持不變即可
2). 這個請求會傳回我們登陸所需要的資訊傳回值是一個xml資料如下所示
<error><ret>0</ret><message>OK</message><skey>@crypt_b13bcf4_edeadfd5xxxxd5e6b289b614fac25e5ac</skey><wxsid>HON+SKvxxxxTihHV</wxsid><wxuin>8xxxx5640</wxuin><pass_ticket>um3UATy9MNzcwDDkVT4xxxxMn5B25G%2FcYIAVbpHnF8vU23yMflmUCFsZkMKbIJIP</pass_ticket><isgrayscale>1</isgrayscale></error>
為了我的隐私我把傳回值做了一定的打碼~~
ret: 表示請求傳回狀态碼0表示成功
skey和wxsid以及wxuin都是具體微信使用者的資訊不會變的在後續的通信過程中需要用到
pass_ticket: 這個值在初始化登入頁面的時候需要用到
5. 現在我們已經拿到了使用者認證相關的資訊包括skey和wxsid以及wxuin需要初始化登入頁面
什麼是初始化登入頁面也就是我們平時登入APP用戶端看到的那個頁面我們需要發送一個請求到服務端拿到資料擷取到常用的聯系人和微信公衆号
如下圖所示這個請求是一個post請求需要我們帶一些使用者認證相關的資訊到服務端
1). ok讓我們分析一下這個請求url: https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-979155549&pass_ticket=um3UATy9MNzcwDDkVT4xxxxMn5B25G%252FcYIAVbpHnF8vU23yMflmUCFsZkMKbIJIP
r: 随機的9位資料
pass_ticke: 從上一步請求傳回值中擷取的資料
2). post請求所需要的data如下所示
{
'BaseResponse': {
'Uin': wxuin,
'Sid': wxsid,
'Skey': skey,
'DeviceID': //15位随機串 'e'+str(random.random())[2:17]
}
}
3). 請求傳回資料如下所示
Ret: 0表示傳回成功ContactList表示的是聯系人清單。
傳回資料包含了目前登入賬戶的相關資訊比如wxuid昵稱 ...
6. 登入成功接下來我們要做的就是開啟消息狀态通知。
ok繼續看此時的網絡請求會發現用戶端向服務端發送了一個post請求
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify?pass_ticket=um3UATy9MNzcwDDkVT42sVxMn5xxxx%252FcYIAVbpHnF8vU23yMflmUCFsZkMKbIJIP
1). 對于這個請求相信大家都不會感到陌生就隻有一個參數pass_ticket同上
2). post請求需要的data模式如下
}
'ClientMsgId': 13位時間戳,
'Code': 3 //固定值
'FromUserName': userNmae, //從初始化登入資訊那邊取到
'ToUserName': userNmae, //從初始化登入資訊那邊取到
}
3. 請求傳回一個json資料
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
},
"MsgID": "4049260553244269433"
}
Ret:0表示的是請求傳回成功狀态
7. ok到目前為止我們以及成功登入了微信并且開啟了消息通知
讓我繼續檢視網頁用戶端會發現有非常多如下圖所示的請求。從請求名稱中我們知道這些請求在進行 同步重新整理輪詢檢查服務端的消息
1). 分析下目前get請求https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck?r=1469858460705&skey=%40crypt_b13bcf4_edeadfdxxxxx5e6b289b614fac25e5ac&sid=HON%2BSKxxxxxxxxxV&uin=828xxxx40&deviceid=e477405243870570&synckey=1_653921573%7C2_653921810%7C3_653921702%7C11_653919729%7C13_653890051%7C201_1469858241%7C1000_1469856425%7C1001_1469851411&_=1469857970652
a. r --> 13位時間戳
b. skey 同上,需要url quote
c. sid 同上
d. devicedid 同上
e. synckey由 初始化登入頁面資訊傳回串中Sync的list清單組成, 需要url quote
f. _ 13位時間戳
2). 請求傳回json資料如下所示window.synccheck={retcode:"0",selector:"0"}
retcode:
a. 0 正常
b. 1100 失敗/登出微信
c. 1101 從其它裝置登入微信網頁版
selector:
b. 2 新的消息
c. 7 手機操作了微信
8. ok萬事具備隻需要知道如何擷取消息和發送消息即可了。
讓我們先看一下當我們在網頁上收到消息的時候不斷輪詢的同步重新整理請求會傳回window.synccheck={retcode:"0",selector:"2"} 或者是 window.synccheck={retcode:"0",selector:"6"}
1). 這個時候我們發現用戶端會向服務端發送一個post請求拉取新的消息資料如下圖所示
post請求: https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=HONxxxxxqSwTihHV&skey=@crypt_b13bcf4_edeadfd5615d5xxxxx9b614fac25e5ac&pass_ticket=um3UATy9MNzcwDDkVTxxxxxMn5B25G%252FcYI
請求所帶的參數同上
2). 請求會傳回json資料包含具體的消息資料和類型
a. BaseResponseRet位0表示傳回成功
b. AddMsgCount 表示新消息個數
c. AddMsgList 表示新消息清單
MsgType 說明
1 文本消息
3 圖檔消息
34 語音消息
37 VERIFYMSG
40 POSSIBLEFRIEND_MSG
42 共享名片
43 視訊通話消息
47 動畫表情
48 位置消息
49 分享連結
50 VOIPMSG
51 微信初始化消息
52 VOIPNOTIFY
53 VOIPINVITE
62 小視訊
9999 SYSNOTICE
10000 系統消息
10002 撤回消息
10. 最後讓我們來看一下如何發送一個消息
1). 當我發送一個消息給好友的時候實際是執行了一次post請求如下圖
url: https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket=um3UATy9MNzcwDDkVT42sVxxxxxxxxG%252FcYIAVbpHnF8vU23yMflmUCFsZkMKbIJIP
2). post請求需要的data如下所示
'BaseResponse': {
'Uin': wxuin,
'Sid': wxsid,
'Skey': skey,
'DeviceID': //15位随機串 'e'+str(random.random())[2:17]
}
'Type': //消息類型同上
'Content': //消息内容
'FromUserName': //發送使用者
'ToUserName': //接受使用者
'LocalID': //13位時間戳+4位随機數
'ClientMsgId': //同LocalId
}
3). 當發送成功之後服務端傳回json資料
"MsgID": "2882629525509760458",
"LocalID": "14698626523310328"
Ret0表示發送成功
ok到此我們就知道了整個微信網頁版從登陸到資料發送的整個過程。
現在我們隻剩下最後一步機器人了。
我們要實作的是收到消息後自動根據消息進行回複。
這個我們隻需要在收到消息的時候利用收到的消息調用“圖靈機器人”API擷取智能回答的資料然後發送給朋友即可。
圖靈機器人http://www.tuling123.com/
歡迎來拍磚github源碼: https://github.com/chenguolin/weixin_robot
二. 效果分析
我申請了個圖靈機器人取名為[【呆萌小白】
下面是簡單的和機器人的對話無聊~~