Request 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&_=1552006589440
微信的登录请求URl
取到后十三位数字,进行拼接,然后发起请求。
ctime = time.time() t = int(ctime*1000)
请求结果中得到uuid,
Request URL: https://login.weixin.qq.com/qrcode/QbTJp0CvmA==
拼接uuid,向后台发送请求。拿到url,向html展示。
Request URL:
https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=4YSNlh_5MA==&tip=1&r=-1524271316&_=1552007464727
向后台不断发起请求,检测是否有扫码
没有扫码,code408,扫了未确认,code201,扫了确认,code200.
扫码之后,拿到头像,avator = re.findall("window.userAvatar = ‘(.*?)‘",r1.text),确认之后,拿到重定向url
拿到重定向url进行拼接后,拿到返回值。
拿到返回值的内容,拼接pass_ticket向后台发送数据,拿返回值
from flask import Flask, render_template, session, jsonify,request import requests import time import re from bs4 import BeautifulSoup import io,sys sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding=‘gb18030‘) app = Flask(__name__) app.secret_key = ‘qweewqdsadasd‘ def xml_parse(arg): r_dict = {} soup = BeautifulSoup(arg, ‘html.parser‘) list = soup.find(name=‘error‘).find_all() for i in list: r_dict[i.name] = i.text return r_dict @app.route(‘/login‘) def login(): ctime = time.time() t = int(ctime * 1000) url1 = ‘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&_={0}‘.format( t) r1 = requests.get(url=url1) qcode = re.findall(‘uuid = "(.*?)"‘, r1.text)[0] session[‘qcode‘] = qcode url2 = ‘https://login.weixin.qq.com/qrcode/‘ + qcode return render_template(‘login.html‘, url2=url2) @app.route(‘/get_login‘) def get_login(): print(‘进入get—login‘) ctime = time.time() t = int(ctime * 1000) qcode = session.get(‘qcode‘) url = ‘https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid={0}&tip=0&r=-728649202&_={1}‘.format( qcode, t) r1 = requests.get(url=url) ret = {‘code‘: ‘‘} if ‘window.code=408;‘ in r1.text: ret[‘code‘] = 408 if ‘window.code=201;‘ in r1.text: print(‘进入到这里了‘) ret[‘code‘] = 201 # 用户扫码还未确认登录,获取用户头像 avator = re.findall("window.userAvatar = ‘(.*?)‘", r1.text) ret[‘avator‘] = avator if ‘window.code=200;‘ in r1.text: ret[‘code‘] = 200 url2 = re.findall(‘window.redirect_uri="(.*?)"‘, r1.text)[0] # 取redirect_url print(url2) url3 = url2 + ‘&fun=new&version=v2‘ # 在rediret_url后加上内容,继续访问 r3 = requests.get(url=url3) # 取到拼接后的redirect_url,访问, res_dict = xml_parse(r3.text) session[‘res_dict‘] = res_dict cookies = r3.cookies.get_dict() print(‘cookies‘, cookies) session[‘cookies‘] = cookies return jsonify(ret) @app.route(‘/index‘) def index(): pass_ticket = session[‘res_dict‘][‘pass_ticket‘] get_url = ‘https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-738766741&lang=zh_CN&pass_ticket={0}‘.format( pass_ticket) r4 = requests.post( url=get_url, json={ ‘BaseRequest‘: { ‘DeviceID‘: ‘e162780575192252‘, ‘Sid‘: session[‘res_dict‘][‘wxsid‘], ‘Skey‘: session[‘res_dict‘][‘skey‘], ‘Uin‘: session[‘res_dict‘][‘wxuin‘] } } ) r4.encoding = ‘utf8‘ init_dict = r4.json() # 相当于json.loads # print(‘init_dict:::‘,init_dict) return render_template(‘index.html‘, init_dict=init_dict) @app.route(‘/user_list‘) def user_list(): """ 获取联系人列表 :return: """ # https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=Q4pDjGjjdjOnFwfHS5I3XFzFc4ApHkTaKzlCOdh34uTVavWegV%252BUky37VviDufnO&r=1530064956758&seq=0&skey=@crypt_2ccf8ab9_fbbb31c98b1a1c12b4ec707678dd336e ctime = int(time.time() * 1000) pass_ticket = session[‘res_dict‘][‘pass_ticket‘] skey = session[‘res_dict‘][‘skey‘] contact_url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket={0}&r={1}&seq=0&skey={2}".format( pass_ticket, ctime, skey) res = requests.get( url=contact_url, cookies=session[‘cookies‘] ) res.encoding=‘utf-8‘ user_list = res.json() print(type(user_list)) print(user_list) return render_template(‘user_list.html‘, userlist=user_list) @app.route(‘/get_img‘) def get_img(): prev = request.args.get(‘prev‘) # /cgi-bin/mmwebwx-bin/webwxgeticon?seq=686005187 username = request.args.get(‘username‘) # @9c4df5e041eb06725a410a3d9d580877e229066895b3e91d44a7af8be37e0e5b skey = request.args.get(‘skey‘) # @crypt_ac8812af_a5601beadce3211cdb4fd3663d08ab52 head_img_url = "https://wx.qq.com{0}&username={1}&skey={2}".format(prev,username,skey) rep = requests.get( url=head_img_url, cookies=session[‘cookies‘] ) return rep.content if __name__ == ‘__main__‘: app.run()
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div > <h3>扫码登录</h3> <img id="userAvator" src={{ url2 }} alt="" style="height: 100px;width: 100px"> </div> <script src="/static/jquery-3.3.1.min.js"></script> <script> $(function(){ checkLogin(); }); function checkLogin(){ $.ajax({ url:‘/get_login‘, dataType:‘json‘, type:‘GET‘, success:function(arg){ if(arg.code ===408){ checkLogin() }else if(arg.code === 201){ $(‘#userAvator‘).attr(‘src‘,arg.avator); checkLogin() }else if(arg.code === 200){ console.log(123); location.href=‘/index‘ } } }) } </script> </body> </html>
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>欢迎使用微信{{ init_dict.User.NickName }}</h1> <h1>最近联系人</h1> <ol type="1" start="1"> {% for foo in init_dict.ContactList %} <li>{{ foo.NickName }}</li> {% endfor %} </ol> <li><a href="/user_list">查看所有联系人</a></li> <h3>最近公众号</h3> {% for item in init_dict.MPSubscribeMsgList %} <div> <h3>{{ item.NickName }}</h3> <ul> {% for msg in item.MPArticleList %} <li><a href="{{ msg.Url }}">{{ msg.Title }}</a></li> {% endfor %} </ul> </div> {% endfor %} } </body> </html>
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h1>联系人列表</h1> <ul> {% for user in userlist.MemberList %} <li> <img style="height: 50px;width: 50px;" src="/get_img?prev={{user.HeadImgUrl}}"> <span>用户名:{{user.NickName}} 唯一标识:{{user.UserName}}</span> </li> {% endfor %} </ul> </body> </html>