基于flask开发web微信

流程

阶段一

目标:基于falsk编写登录页面,获取二维码

解析:1:、二维码图片地址有个后缀字符串

2、图片生成之前,先获取到随机字符串再生成二维码

3、二维码的图片的来源

4、时间戳

from flask import Flask,request,render_template
import time  # 获取时间戳
import requests
import re
app = Flask(__name__)

# app.run(debug=True)   or
app.debug = True

@app.route(‘/login‘,methods=[‘GET‘,‘POST‘])
def login():
    if request.method == ‘GET‘:
        ctime = str(int(time.time() * 1000))
        qcode_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&_={0}‘.format(ctime)
        ret = requests.get(qcode_url)
        print(ret.text)
        # 正则 匹配出来uuid
        qcode = re.findall(‘uuid = "(.*)";‘,ret.text)[0]
        print(qcode)
        return render_template(‘login.html‘,qcode=qcode)
    else:
        pass

if __name__ == ‘__main__‘:
    app.run()

manage.py

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>登录页面</title>
</head>
<body>
<div style="width: 200px;margin: 0 auto">
    <h1 style="text-align: center">微信登录</h1>
    <img style="height: 200px;width: 200px" src="https://login.weixin.qq.com/qrcode/{{qcode}}" alt="">
</div>

</body>
</html>

login

效果

阶段二

目标:获取头像

长轮询

长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,    客户端处理完响应信息后再向服务器发送新的请求。
优点:在无消息的情况下不会频繁的请求,耗费资源小。
缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。
实例:WebQQ、Hi网页版、Facebook IM。

1、长轮询

2:检测用户是否扫码,未扫码的状态码为408

3:扫码成功,并获取用户头像

利用ajax写长轮询

    <!--制作长轮询-->
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script>
        $(function () {
            checkLogin();
        });

        function checkLogin() {
           $.ajax({
               url:‘/check_login‘,
               type:‘GET‘,
               dataType:‘JSON‘,  //  指定数据类型
               success:function (arg) {
                   // 扫码
                   $(‘#img‘).attr(‘src‘,arg.src);
                   checkLogin()
               }
           })
        }
    </script>

@app.route(‘/check_login‘)
def check_login():
    import time
    time.sleep(10)
    return ‘asassassas‘

manage

@app.route(‘/check_login‘)
def check_login():
    ‘‘‘
    未扫码的状态码为408,及其连接
    https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=YdXFD_pPqg==&tip=0&r=-1052203142&_=1525764993167
    需要uuid及其时间戳
    :return:
    ‘‘‘
    response = {‘code‘:408}
    qcode = session.get(‘qcode‘)
    ctime = str(int(time.time() * 1000))
    check_url = ‘https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid={0}&tip=0&r=-1052203142&_={1}‘.format(qcode,ctime)
    #  发送get请求检测是否扫码
    ret = requests.get(check_url)
    print(ret.text)   # 不扫码则返回408 window.code=408;
    if "code=201" in ret.text:
        # 扫码成功 生成用户头像
        src = re.findall("userAvatar = ‘(.*)‘;",ret.text)[0]
        # print(src)   # 获取到用户的头像地址
        response[‘code‘] = 201
        response[‘src‘] = src

    return jsonify(response)
if __name__ == ‘__main__‘:
    app.run()

manage

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>登录页面</title>
</head>
<body>
    <div style="width: 200px;margin: 0 auto">
        <h1 style="text-align: center">微信登录</h1>
        <img id="img" style="height: 200px;width: 200px" src="https://login.weixin.qq.com/qrcode/{{qcode}}" >
    </div>

    <!--制作长轮询-->
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script>
        $(function () {
            checkLogin();
        });

        function checkLogin() {
           $.ajax({
               url:‘/check_login‘,
               type:‘GET‘,
               dataType:‘JSON‘,  //  指定数据类型
               success:function (arg) {
                   if(arg.code === 201){
                        // 扫码
                        $(‘#img‘).attr(‘src‘,arg.src);
                   }else if(arg.code === 200){
                       // 重定向到用户信息列表
                       location.href = ‘/index‘
                   }else {
                       checkLogin();
                   }
               }
           })
        }
    </script>

</body>
</html>

login

阶段三:

确认登录

1、获取凭证信息

接着会往这个地址发送请求,获取凭证(xml格式)

注意

确认登录的地址

https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=A9QalHCk6CY9iVdnpY9WP9os@qrticket_0&uuid=QcVoiPFXYw==&lang=zh_CN&scan=1525771690

获取凭证地址

https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?[email protected]_0&uuid=QcVoiPFXYw==&lang=zh_CN&scan=1525771690&fun=new&version=v2&lang=zh_CN

初始化

当发的数据是json格式就用payload

为字典格式  发送过去的数据BaseRequest:
{Uin: "736490221", Sid: "5S/x/NshjYS7Oq1T", Skey:"@crypt_34187f1b_b2d9f745b8ea17106a3aed8f64b6bd36",…}
DeviceID:"e132063792738476"
Sid:"5S/x/NshjYS7Oq1T"
Skey:"@crypt_34187f1b_b2d9f745b8ea17106a3aed8f64b6bd36"
Uin:"736490221"
上面是需要凭证的一些内容凭证的数据<error>
<ret>0</ret>
<message></message><skey>@crypt_34187f1b_94ee8455819fb0b67ee356a1d34f6d7c</skey><wxsid>oWrr1oPRVKLNs4SI</wxsid>
<wxuin>736490221</wxuin><pass_ticket>svwwPifX3lEpWr36wXSEc4ufYTQZ9r5i6UmJvTXxfz168gMQtXuSskG%2FCb5%2B3tfy</pass_ticket>
<isgrayscale>1</isgrayscale>
</error>
最终取值方式   
ticket_dict = session.get(‘ticket_dict‘)init_url = ‘https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-1058298025&lang=zh_CN&pass_ticket={0}‘.format(ticket_dict.get("pass_ticket"))data_dict = {    "BaseRequest":{        "DeviceID":"e132063792738476",        "Sid":ticket_dict.get("wxsid"),        "Skey":ticket_dict.get("Skey"),        "Uin":ticket_dict.get("wxuin")    }}

@app.route(‘/check_login‘)
def check_login():
    ‘‘‘
    未扫码的状态码为408,及其连接
    https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=YdXFD_pPqg==&tip=0&r=-1052203142&_=1525764993167
    需要uuid及其时间戳
    :return:
    ‘‘‘
    response = {‘code‘:408}
    qcode = session.get(‘qcode‘)
    ctime = str(int(time.time() * 1000))
    check_url = ‘https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid={0}&tip=0&r=-1052203142&_={1}‘.format(qcode,ctime)
    #  发送get请求检测是否扫码
    ret = requests.get(check_url)
    # print(ret.text)   # 不扫码则返回408 window.code=408;
    if "code=201" in ret.text:
        # 扫码成功 生成用户头像
        src = re.findall("userAvatar = ‘(.*)‘;",ret.text)[0]
        # print(src)   # 获取到用户的头像地址
        response[‘code‘] = 201
        response[‘src‘] = src
    elif ‘code=200‘ in ret.text:
        # 确认登录
        ‘‘‘
        window.redirect_uri="https://wx2.qq.com/cgi-bin/mmwebwx-bin/[email protected]_0&uuid=4bMd7uwPpg==&lang=zh_CN&scan=1525769290";
        ‘‘‘
        # 获取凭证的地址
        redirect_url = re.findall(‘redirect_uri="(.*)";‘,ret.text)[0]
        # 到取凭证的地址得到凭证
        redirect_uri = redirect_url + "&fun=new&version=v2"
        ticket_ret = requests.get(redirect_uri)
        print(ticket_ret.text)
        # 解析  字典
        ticket_dict = xml_parser(ticket_ret.text)
        # 下面初始化需用到凭证
        session[‘ticket_dict‘] = ticket_dict
        response[‘code‘] = 200
    return jsonify(response)

确认登录

关于解析xml数据

方式一:children

from bs4 import BeautifulSoup

text ="""<error><ret>0</ret>
<message></message><skey>@crypt_2ccf8ab9_70b4bfadb5aeb520357d4ecf46c23713</skey><wxsid>xryEESU5QgXX61ji</wxsid><wxuin>981579400</wxuin><pass_ticket>3nIORdKsOyenOh1%2FoH4U17Qhw8YBkGHJl%2BfqVvaoGoDnmBoQxEJdA%2BZyuHixW1Ow</pass_ticket><isgrayscale>1</isgrayscale></error>"""

soup = BeautifulSoup(text,‘html.parser‘)
div = soup.find(name=‘error‘)
for i  in div.children:
    print(i)

children

方式二:find_all,参数recursive,=True(递归,往子子孙孙里面找) =false(只找儿子)

from bs4 import BeautifulSoup

def xml_parser(text):
    dic = {}
    soup = BeautifulSoup(text,‘html.parser‘)
    div = soup.find(name=‘error‘)
    for item in div.find_all(recursive=False):
        dic[item.name] = item.text
    return dic

text ="""<error><ret>0</ret>
<message></message><skey>@crypt_2ccf8ab9_70b4bfadb5aeb520357d4ecf46c23713</skey><wxsid>xryEESU5QgXX61ji</wxsid><wxuin>981579400</wxuin><pass_ticket>3nIORdKsOyenOh1%2FoH4U17Qhw8YBkGHJl%2BfqVvaoGoDnmBoQxEJdA%2BZyuHixW1Ow</pass_ticket><isgrayscale>1</isgrayscale></error>"""

dic = xml_parser(text)
print(dic)

find_all

阶段四:

目标:用户初始化,发送POST请求:、

from flask import Flask,request,render_template,session,jsonify
import time  # 获取时间戳
import requests
import re
from bs4 import BeautifulSoup

app = Flask(__name__)

# app.run(debug=True)   or
app.debug = True
app.secret_key = ‘safsfsfs‘    #  生成密钥, 头像

# 解析xml文件
def xml_parser(text):
    dic = {}
    soup = BeautifulSoup(text,‘html.parser‘)
    div = soup.find(name=‘error‘)
    for item in div.find_all(recursive=False):
        dic[item.name] = item.text
    return dic

@app.route(‘/login‘,methods=[‘GET‘,‘POST‘])
def login():
    if request.method == ‘GET‘:
        ctime = str(int(time.time() * 1000))
        qcode_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&_={0}‘.format(ctime)
        ret = requests.get(qcode_url)
        print(ret.text)
        # 正则 匹配出来uuid
        qcode = re.findall(‘uuid = "(.*)";‘,ret.text)[0]
        # 将uuid放到session里面以便下面调用
        session[‘qcode‘] = qcode
        print(qcode)
        return render_template(‘login.html‘,qcode=qcode)
    else:
        pass

@app.route(‘/check_login‘)
def check_login():
    ‘‘‘
    未扫码的状态码为408,及其连接
    https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=YdXFD_pPqg==&tip=0&r=-1052203142&_=1525764993167
    需要uuid及其时间戳
    :return:
    ‘‘‘
    response = {‘code‘:408}
    qcode = session.get(‘qcode‘)
    ctime = str(int(time.time() * 1000))
    check_url = ‘https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid={0}&tip=0&r=-1052203142&_={1}‘.format(qcode,ctime)
    #  发送get请求检测是否扫码
    ret = requests.get(check_url)
    # print(ret.text)   # 不扫码则返回408 window.code=408;
    if "code=201" in ret.text:
        # 扫码成功 生成用户头像
        src = re.findall("userAvatar = ‘(.*)‘;",ret.text)[0]
        # print(src)   # 获取到用户的头像地址
        response[‘code‘] = 201
        response[‘src‘] = src
    elif ‘code=200‘ in ret.text:
        # 确认登录
        ‘‘‘
        window.redirect_uri="https://wx2.qq.com/cgi-bin/mmwebwx-bin/[email protected]_0&uuid=4bMd7uwPpg==&lang=zh_CN&scan=1525769290";
        ‘‘‘
        # 获取凭证的地址
        redirect_url = re.findall(‘redirect_uri="(.*)";‘,ret.text)[0]
        # 到取凭证的地址得到凭证
        redirect_uri = redirect_url + "&fun=new&version=v2"
        ticket_ret = requests.get(redirect_uri)
        print(ticket_ret.text)
        # 解析  字典
        ticket_dict = xml_parser(ticket_ret.text)
        # 下面初始化需用到凭证
        session[‘ticket_dict‘] = ticket_dict
        response[‘code‘] = 200
    return jsonify(response)

@app.route(‘/index‘)
def index():
    ‘‘‘
    用户初始化:
        https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-1058298025&lang=zh_CN&pass_ticket=9179zbgvzg%252BstA95JF5QmlL1mQ%252BLKqunCOs56ac%252FejGXMC9WrgwRoUi4N7xkdDNL
    ‘‘‘
    ticket_dict = session.get(‘ticket_dict‘)
    init_url = ‘https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-1058298025&lang=zh_CN&pass_ticket={0}‘.format(ticket_dict.get("pass_ticket"))
    data_dict = {
        "BaseRequest":{
            "DeviceID":"e132063792738476",
            "Sid":ticket_dict.get("wxsid"),
            "Skey":ticket_dict.get("Skey"),
            "Uin":ticket_dict.get("wxuin")
        }
    }
    r1 = requests.post(
        url=init_url,
        json=data_dict
    )
    # 编码
    r1.encoding = ‘utf-8‘
    user_dict = r1.json()
    print(user_dict)

    return render_template(‘/index.html‘,user_dict=user_dict)
if __name__ == ‘__main__‘:
    app.run()

初始化

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <h1>欢迎登录:{{user_dict.User.NickName}}</h1>
    <h3>最近联系人</h3>
    <ul>
        {% for user in user_dict.ContactList%}
        <li>{{user.NickName}}</li>
        {% endfor %}

</body>
</html>

index

注意

这里发送过去的是json类型

    r1 = requests.post(
        url=init_url,
        # 方式一:默认将json的请求发过去
        json=data_dict
        # 方式二:自己写json数据  需要将请求头写上
        # data = json.dumps(data_dict)
        # headers={
        #     ‘Content-Type‘:‘application/json‘
        # }
    )

原文地址:https://www.cnblogs.com/jassin-du/p/9010708.html

时间: 2024-11-09 00:10:42

基于flask开发web微信的相关文章

基于Flask 实现Web微信登陆

网页版微信登陆网址 https://login.wx.qq.com/ 获取微信登陆的二维码 在浏览器中访问登陆接口 https://login.wx.qq.com/ 我们查找二维码的图片可以看到 其中src为 https://login.weixin.qq.com/qrcode/Yd5dz5xUnw==" 而我们每次刷新都会生成一个新的二维码 多刷新几次我们会发现二维码中src最后面的qrcode/......值每次都会改变 ,索引肯定会有一些请求可以获取这些值 我们继续追踪发现下面的地址会返回

第二章 基于JAX-WS开发Web services

基于JAX-WS开发Web services 这篇文章纯属搬砖. 转载于:http://www.ithov.com/linux/125942_4.shtml. Web Services 是一种面向服务的技术,通过标准的 Web 协议提供服务,目的是保证不同平台的应用服务可以互操作.依据 web services 规范实施的应用之间,无论它们所使用的语言. 平台或内部协议是什么,都可以相互交换数据,这就是 web services 的好处.本文选择 IBM WebSphere Applicatio

Python 基于Flask的Web开发【1】【用户登录 注册】

实现目标 基于Flask实现用户的登录/注册. 设计思路 前端1.编写登录和注册表单2.编写视图函数3.编写相应的html文件4.页面测试 后台1.创建数据库2.修改配置文件3.编写数据表类并生成数据表4.修改视图函数,实现数据交互 前端实现 1.编写登录和注册表单(/app/home/forms.py) # 导入表单基类 from flask_wtf import FlaskForm # 导入需要用到的表格类型 from wtforms import StringField, Password

[翻译]基于WebView开发Web APP

作者:zhanhailiang 日期:2015-01-30 原文链接:Building Web Apps in WebView 基于Android视图类WebView,可以直接在Activity Layout中展示Web页面,这样可以增强更新的灵活性.简单理解,WebView展示HTML页面,但是其本身并不支持浏览器的常用功能,诸如浏览进度控制,地址栏等. 使用场景&实现 场景1 对于应用程序中需要频繁更新的模块,可以使用WebView来实现,这样更新内容即可实时更新,诸如用户协议页面,新手引导

基于Flask的Web应用部署到SAE上遇到的问题

我的应用底层数据库用的是MySQL,利用Flask-SQLALchemy实现接口操作.我遇到的问题是: 在我把代码部署到SAE上后,当数据向数据库insert的时候总是出现“2006,MySQL has gone away”的问题. 查了官方文档和Google了很多,首先是用如下方法去做的: 1.SQLAlchemy_POOL_SIZE = 10 2.每次操作之后关闭数据库 def init_after_handlers(app): @app.teardown_appcontext def te

使用flask开发网站后端

Flask 是一个用于 Python 的微型网络开发框架,可以用于快速的搭建一个小型的网站. 我的搜索引擎:http://www.abelkhan.com 就是基于flask开发 一个flask的Hello World from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run()

《Flask Web开发 基于Python的Web应用开发实战》简评

指路牌 <Flask Web开发><Flask Web开发 基于Python的Web应用开发实战><Flask Web开发>是否适合新手入门Python Web开发? 正文 <Flask Web开发 基于Python的Web应用开发实战>,O'Reilly"动物书系列"的"狗书",应该是很多Flask初学者被推荐使用的入门书,但是这本书真的适合初学者吗? Python的Web框架非常多,例如Django.Flask.T

基于Flask框架的Python web程序的开发实战 &lt;一&gt; 环境搭建

最近在看<Flask Web开发基于Python的Web应用开发实战>Miguel Grinberg著.安道译 这本书,一步步跟着学习Flask框架的应用,这里做一下笔记 电脑只安装一个Python2.7就行了,用的IDE还是官方那个跟记事本差不多的编辑器,先原始一点,以后再用PyCharm开发,我系统是Win8.1 x64 一:虚拟环境配置 虚拟环境使用第三方工具virtualenv创建,打开cmd,输入virtualenv命令来检测是否已经安装,我已经装过了,所以会提示:You must

Flask之旅《Flask Web开发:基于Python的Web应用开发实战》学习笔记

<Flask Web开发:基于Python的Web应用开发实战> 点击上方的"目录"快速到达哦! 虽然简单的网站(Flask+Python+SAE)已经上线,但只是入门.开发大型网站,系统地学习一遍还是有必要的. 1 虚拟环境 2016-6-8 书上介绍了 virtualenv,每个venv都会拷贝一份packages到项目 /venv目录. virtualenv venv venv\Scripts\activate.bat (venv) $ pip freeze >