文章所使用Python版本為py3.5 1.微信服務(wù)器返回一個會話ID 微信Web版本不使用用戶名和密碼直接登錄,而是采用二維碼登錄,所以服務(wù)器需要首先分配一個唯一的會話ID,用來標識當前的一次登錄。 通過查看網(wǎng)絡(luò)請求我們找到了這個 二維碼圖片代表的隨機字符串,(IcelandB9Entig==), 2.通過會話ID獲得二維碼 然后找到該隨機字符串的來源請求 請求方式為 GET形式 , 具體連接為: https://login.wx.qq.com/jslogin? 我們只需要改變最后一個變量 _值即可獲得新的字符串序列: (這個值是當前距離林威治標準時間的毫秒)可以自行構(gòu)造! 通過分割,我們就可以獲得隨機字符串,自己在前端頁面上構(gòu)造一個二維碼出來. ![]() ![]()
3.輪詢手機端是否已經(jīng)掃描二維碼并確認在Web端登錄 當我們還沒進行掃碼登錄時,發(fā)現(xiàn)微信web網(wǎng)頁會自動向服務(wù)器 輪詢手機端是否已經(jīng)掃碼并且確認登錄!! 每一分鐘發(fā)送一次,如果沒有登錄,請求會返回
掃碼后為
確認登陸后為:
需要獲得其中的跳轉(zhuǎn)url,對rensponse進行分割后取得。 redirect_url = re.split('=', http_res_code.text, 2)[-1].strip().replace('"', '').replace(';', '') 4.訪問登錄地址,獲得uin和sid 在接下來的連接中,我們發(fā)現(xiàn)服務(wù)器發(fā)給了我們skey,sid,pass_ticket 的重要信息, 分析發(fā)現(xiàn)該請求的發(fā)送地址為: GET方式, https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=A_ToQqd_AFXpsrLMH6RNgi3W@qrticket_0&uuid=we6XJEZYDg==&lang=zh_CN&scan=1492592531 發(fā)現(xiàn),該請求地址為 跳轉(zhuǎn)url + &fun=new&version=v2 構(gòu)造而成! 直接GET發(fā)送請求,我們就拿到返回信息,發(fā)現(xiàn)是 xml 格式的數(shù)據(jù)! 構(gòu)造一個方法方便獲取我們的連接信息 def auth_analysis(self,str_xml): ''' xml中取出數(shù)據(jù),返回字典 :param http_res_ticket: :return: ''' from xml.etree import ElementTree as ET root = ET.XML(str_xml) ret = {} for child in root: ret[child.tag] = child.text return ret 我們還需要獲得該請求下的cookies參數(shù),直接通過requests模塊的 requests.cookies.get_dict() # 獲取xml 登錄信息 user_ticket_url = redirect_url+ '&fun=new&version=v2' user_xml_ticket = requests.get(user_ticket_url) TICKET_COOKIR = user_xml_ticket.cookies.get_dict() ALL_COOKIE_DICT.update(TICKET_COOKIR) #記錄cookies # 獲取xml中信息 user_ticket_dic = self.auth_analysis(user_xml_ticket.text) USER_RESULT_DICT.update(user_ticket_dic) #記錄xml中的具體信息 5.初使化微信信息 # 初始化Url : USER_INIT_URL = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?pass_ticket={0}&skey={1}&r={2}' pass_ticket,skey為上一步驟獲得的xml信息樹中,r為時間戳 ![]() 這一步的發(fā)送請求,使用了urllib.requests來發(fā)送,注意格式轉(zhuǎn)換! 此時我們已經(jīng)獲得了服務(wù)端返回的部分數(shù)據(jù).如果需要進一步獲取全部信息,......如下 6.獲得所有的好友列表 該請求返回了全部的用戶信息. https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact? 構(gòu)造請求并發(fā)送: ![]() 7.保持與服務(wù)器的信息同步 與服務(wù)器保持同步需要在客戶端做輪詢,該輪詢的URL如下: https://webpush.wx2.qq.com/cgi-bin/mmwebwx-bin/synccheck? skey,sid,uin,與上面步驟的值相對應(yīng)此處的synkey是上步步驟獲得的同步鍵值,但需要按一定的規(guī)則組合成以下的字符串: 1_124125|2_452346345|3_65476547|1000_5643635 ![]() | 被URL編碼成%7C,通過對上面的地址發(fā)送請求:,
會返回如下的字符串:
當有人發(fā)送信息給你時, :
8.獲得別人發(fā)來的消息 我們通過該URL地址獲取發(fā)送給我們的消息: https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsync? sid=XQvf1MmZ7W8O2BU2 &skey=@crypt_75efaa00_3afa77c01d45461eef7eac88da37f70d &pass_ticket=YArFw%252BDpJHCpRtKCTTabpe2ytETBDmYsp%252BB7ywe%252BtplmzxQZ6ohX7d14sJgjgk6T 制造相應(yīng)的payload 發(fā)送GET請求,獲得返回response數(shù)據(jù) ![]() 9.向用戶發(fā)送消息 用戶主動發(fā)送消息,通過以下的URL地址: https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg ?pass_ticket=mRfzOKMZdUAfqrZVaT7VZeroYNX6SgTtO7WzDwDXmiZvwWC0iWlln2fBuGa8oeld 上面的pass_ticket參數(shù)不再解釋了,訪問該URL采用POST方式,payload如以下的格式: ![]() BaseRequest都是授權(quán)相關(guān)的值,與上面的步驟中的值對應(yīng),Msg是對消息的描述,包括了發(fā)送人與接收人,消息內(nèi)容,消息的類型(1為文本),ClientMsgId和LocalID由本地生成。rr可用當前的時間。在返回JSON結(jié)果中BaseResponse描述了發(fā)送情況,Ret為0表示發(fā)送成功。
注意: 該流程在py3環(huán)境下,使用了Tornado框架 和 requests 包 和 urllib.requests 包 urllib.requests 包 具體用法參考如下示例:
完整參考代碼: ![]() ![]() ![]() ![]()
|
|
來自: highoo > 《數(shù)據(jù)分析》