文章所使用Python版本为py3.5 1.微信服务器返回一个会话ID 微信Web版本不使用用户名和密码直接登录,而是采用二维码登录,所以服务器需要首先分配一个唯一的会话ID,用来标识当前的一次登录。 通过查看网络请求我们找到了这个 二维码图片代表的随机字符串,(IcelandB9Entig==), 2.通过会话ID获得二维码 然后找到该随机字符串的来源请求 请求方式为 GET形式 , 具体连接为: https://login.wx.qq.com/jslogin? 我们只需要改变最后一个变量 _值即可获得新的字符串序列: (这个值是当前距离林威治标准时间的毫秒)可以自行构造! 通过分割,我们就可以获得随机字符串,自己在前端页面上构造一个二维码出来. ![]() ![]()
3.轮询手机端是否已经扫描二维码并确认在Web端登录 当我们还没进行扫码登录时,发现微信web网页会自动向服务器 轮询手机端是否已经扫码并且确认登录!! 每一分钟发送一次,如果没有登录,请求会返回
扫码后为
确认登陆后为:
需要获得其中的跳转url,对rensponse进行分割后取得。 redirect_url = re.split('=', http_res_code.text, 2)[-1].strip().replace('"', '').replace(';', '') 4.访问登录地址,获得uin和sid 在接下来的连接中,我们发现服务器发给了我们skey,sid,pass_ticket 的重要信息, 分析发现该请求的发送地址为: GET方式, https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=A_ToQqd_AFXpsrLMH6RNgi3W@qrticket_0&uuid=we6XJEZYDg==&lang=zh_CN&scan=1492592531 发现,该请求地址为 跳转url + &fun=new&version=v2 构造而成! 直接GET发送请求,我们就拿到返回信息,发现是 xml 格式的数据! 构造一个方法方便获取我们的连接信息 def auth_analysis(self,str_xml): ''' xml中取出数据,返回字典 :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参数,直接通过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为时间戳 ![]() 这一步的发送请求,使用了urllib.requests来发送,注意格式转换! 此时我们已经获得了服务端返回的部分数据.如果需要进一步获取全部信息,......如下 6.获得所有的好友列表 该请求返回了全部的用户信息. https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact? 构造请求并发送: ![]() 7.保持与服务器的信息同步 与服务器保持同步需要在客户端做轮询,该轮询的URL如下: https://webpush.wx2.qq.com/cgi-bin/mmwebwx-bin/synccheck? skey,sid,uin,与上面步骤的值相对应此处的synkey是上步步骤获得的同步键值,但需要按一定的规则组合成以下的字符串: 1_124125|2_452346345|3_65476547|1000_5643635 ![]() | 被URL编码成%7C,通过对上面的地址发送请求:,
会返回如下的字符串:
当有人发送信息给你时, :
8.获得别人发来的消息 我们通过该URL地址获取发送给我们的消息: https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsync? sid=XQvf1MmZ7W8O2BU2 &skey=@crypt_75efaa00_3afa77c01d45461eef7eac88da37f70d &pass_ticket=YArFw%252BDpJHCpRtKCTTabpe2ytETBDmYsp%252BB7ywe%252BtplmzxQZ6ohX7d14sJgjgk6T 制造相应的payload 发送GET请求,获得返回response数据 ![]() 9.向用户发送消息 用户主动发送消息,通过以下的URL地址: https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg ?pass_ticket=mRfzOKMZdUAfqrZVaT7VZeroYNX6SgTtO7WzDwDXmiZvwWC0iWlln2fBuGa8oeld 上面的pass_ticket参数不再解释了,访问该URL采用POST方式,payload如以下的格式: ![]() BaseRequest都是授权相关的值,与上面的步骤中的值对应,Msg是对消息的描述,包括了发送人与接收人,消息内容,消息的类型(1为文本),ClientMsgId和LocalID由本地生成。rr可用当前的时间。在返回JSON结果中BaseResponse描述了发送情况,Ret为0表示发送成功。
注意: 该流程在py3环境下,使用了Tornado框架 和 requests 包 和 urllib.requests 包 urllib.requests 包 具体用法参考如下示例:
完整参考代码: ![]() ![]() ![]() ![]()
|
|