Python具有非常强大的抓包能力,我们可以利用Python的这一优势来做很多有趣的实验,本次内容便是用Python实现网页版微信的登陆。 我们来一步步边实验边探讨原理: 1、我们打开网页版微信的网址https://wx.qq.com/,会发现页面非常简单,只是出现一个让你手机进行扫描登陆的二维码。
那么我们要从何下手呢?这时候我们就需要使用抓包工具来获取网页发出的请求信息和接收到的反馈信息,从中分析出我们所需要的有用信息。可以在浏览器中右键打开审查元素,点击Network选项这便是浏览器自带的抓包工具。现在刷新一下页面,网页会向微信的服务器发出请求并得到服务器的反馈,其间的操作过程都会被抓包工具捕获,我们来查看并分析一下抓到的包:
在左侧的Name下会有许多包的名称,我们点击一个包便能在右侧的Request URL中看到该包请求的网址。
从中可以知道微信登陆请求的网址为https://login.wx.qq.com,请求方式为GET,状态码为200。下面为网页请求的返回值: appid:wx782c26e4c19acffb redirect_uri:https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage fun:new lang:zh_CN _:1465899262409#这是网页发出请求的时间戳,在用python写代码时可用int(time.time())获取
2、依据以上信息,编写获取网页请求返回值的Python代码:
运行代码,获取返回值为window.QRLogin.code = 200; window.QRLogin.uuid = "wZ2RMB6DfQ==";
通过网页访问获取返回值为:window.QRLogin.code = 400; window.QRLogin.error = "";
通过对比两次返回值的结果可知,由于code和uuid的值实时变化导致获取的返回值实时变化,所以需要用正则表达式获取实时值:
其中code的值为整型,所以使用\d获取;uuid值为非空白字符串,用\S获取。 3、现在我们继续审查元素,在抓包工具中找到二维码的请求地址https://login.weixin.qq.com/qrcode/(UUID值)
在程序中,先读取二维码请求地址,将请求信息写在一个字典中,通过Request方法读取请求值并将其返回值写入到response变量中,获取二维码图片并保存后,使用os.system('call %s' %imagesPath)命令打开图片。运行程序,会自动打开二维码:
4、在抓包工具中找到微信登陆请求地址:https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=gckSil83PQ==&tip=1&r=-1328804227&_=1465912650442
我们发现请求地址中有&uuid、&tip、&_ 三个分别代表uuid值、tip值、时间戳的“变量”,所以我们可以再定义一个全局变量tip:
定义判断是否登陆成功的函数,引入url时用%s传递&uuid、&tip、&_的值:
通过Request方法读取请求值并将其返回值写入到response变量中,再读取response的值写入data变量中,输出data值:
5、运行程序,出现二维码后不扫描二维码登录,超时后返回window.code=408,登陆失败:
运行程序,出现二维码后扫描二维码登录,返回window.code=201,表明登陆成功:
由此我们可以利用登陆地址返回值判断是否登陆成功。利用正则表达式获取登陆状态码:
判断登陆状态:
现在便基本实现了用Python程序实现网页版微信的登陆。 7、代码如下: #/usr/bin/env python #_*_coding:utf-8_*_ __author__='Eagle' #version:1.0 import urllib <span style="white-space:pre"> </span>#for web module import urllib2 import os #read system import cookielib #cookie lib import time #time module import sys import re uuid = '' tip = 0 <span style="white-space:pre"> </span>#定义微信登陆请求中tip值 imagesPath =os.getcwd()+'/weixin.jpg' #定义二维码图片路径,os.getcwd()获取当前路径 def getUUID(): #get UUID global uuid #引入全局变量uuid url = 'https://login.weixin.qq.com/jslogin' #登陆请求界面的url values = { 'appid':'wx782c26e4c19acffb', 'redirect_uri':'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage', 'fun':'new', 'lang':'zh_CN', '_':int(time.time()) #时间戳 } #用urllib2中的Request模块(有三个参数,url,data,) #用urllib的urlencode()方法进行编码转换,转换后才能被网页识别 request = urllib2.Request(url=url,data=urllib.urlencode(values)) response = urllib2.urlopen(request) #打开实时请求request data = response.read() #读出response的值 print data #用正则表达式获取网页返回的实时值,\d为int类型,\S为非空白字符 regx = r'window.QRLogin.code = (\d+); window.QRLogin.uuid = "(\S+?)"' pm = re.search(regx,data) code = pm.group(1) uuid = pm.group(2) print code,uuid if code=='200': return True return False def show2DimensionCode(): global tip #引入全局变量tip url = 'https://login.weixin.qq.com/qrcode/'+uuid values ={ 't':'webwx', '_':int(time.time()) } request = urllib2.Request(url=url,data=urllib.urlencode(values)) response = urllib2.urlopen(request) tip =1 f = open(imagesPath,'wb') #以二进制(b)打开二维码图片 f.write(response.read()) #将response获取的值写入img文件中 f.close() time.sleep(1) #延时1秒 os.system('call %s' %imagesPath) #打开图片 #windows中DOS命令中不支持utf-8,这里用u和encode防止乱码 print u'请使用手机微信扫描二维码登录'.encode('GBK') def isLoginSucess(): #获取微信登陆请求地址,读取返回值 url = 'https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?tip=%s&uuid=%s&_=%s'%(tip,uuid,int(time.time())) request = urllib2.Request(url=url) response = urllib2.urlopen(request) data = response.read() print data #data值为window.code=408,登陆失败;为window.code=201,登陆成功 #利用正则表达式获取登陆状态码 regx = r'window.code=(\d+)' pm = re.search(regx,data) code = pm.group(1) #判断登陆状态 if code=='201': print'Scan QR code successfully!' elif code=='200': print'Logining...' elif code=='408': print'Login Timeout!' return code #入口函数 def main(): #获取当前cookie cookie = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar())) urllib2.install_opener(cookie) #判断是否成功获取uuid if getUUID()==False: print'Get uuid unsuccessfully!' return None show2DimensionCode() time.sleep(1) while isLoginSucess() !='200': pass #判断登陆成功,删除二维码 os.remove(imagesPath) print'Login successfully!' if __name__=='__main__': print'Welcome to use weixin personnal version' print'Please click Enter key to continue......'
|