zoukankan      html  css  js  c++  java
  • 基于Flask开发web微信

    1. 获取二维码
      app.py

    import re
    import time
    import requests
    from flask import Flask,render_template
    
    
    app = Flask(__name__)
    app.secret_key = '1231sdfasdf'
    @app.route('/login')
    def login():
    # 1529982725262
    # 15299828432250135
    ctime = 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)

    rep = requests.get(
    url=qcode_url
    )
    # print(rep.text) # window.QRLogin.code = 200; window.QRLogin.uuid = "gb8UuMBZyA==";
    qcode = re.findall('uuid = "(.*)";',rep.text)[0]
    session['qcode'] = qcode
    return render_template('login.html',qcode = qcode)
    if __name__ == '__main__': app.run()

    login.html

    <body>
        <div style=" 200px;margin: 0 auto;">
            <h1 style="text-align: center;">扫码登录</h1>
            <img style=" 200px;height: 200px;" src="https://login.weixin.qq.com/qrcode/{{qcode}}" alt="">
        </div>
    </body>

    2. 检查登录:扫码

    1、登陆的时候需要长连接,一直保持opening的状态

    2、因为第一次访问页面的时间仍然需要用到,不能用g(一次请求己结束),选择用session获取的方式

    from bs4 import BeautifulSoup

    def xml_parse(text):
    result = {}
    soup = BeautifulSoup(text,'html.parser')
    tag_list = soup.find(name='error').find_all()
    for tag in tag_list:
    result[tag.name] = tag.text
    return result

    @app.route('/check/login') def check_login(): qcode = session['qcode'] ctime = int(time.time() * 1000) check_login_url = 'https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid={0}&tip=0&r=-976036168&_={1}'.format(qcode,ctime) rep = requests.get( url=check_login_url ) result = {'code': 408} if 'window.code=408' in rep.text: # 用户未扫码 result['code'] = 408 elif 'window.code=201' in rep.text: # 用户扫码,获取头像 result['code'] = 201 result['avatar'] = re.findall("window.userAvatar = '(.*)';",rep.text)[0] elif 'window.code=200' in rep.text: # 用户确认登录 redirect_uri = re.findall('window.redirect_uri="(.*)";',rep.text)[0] print(redirect_uri) #https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=ASEHe9Kr5Hq0PITHG1dXEBS8@qrticket_0&uuid=gfbq6fFg9Q==&lang=zh_CN&scan=1529986929&fun=new&version=v2 # https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=ATEkrWXwLgR3QjDuYsx-dpzN@qrticket_0&uuid=obFFB7YwVA==&lang=zh_CN&scan=1529986454 redirect_uri = redirect_uri + "&fun=new&version=v2" ru = requests.get(url=redirect_uri) # <error><ret>0</ret><message></message><skey>@crypt_ac8812af_0ffde1190007c7c044bc31ae51407c45</skey><wxsid>fRwfacRtjRFpEIwt</wxsid><wxuin>1062220661</wxuin><pass_ticket>0M1plebTzNQ%2FKaSIfTfk65laCSXUWmjpxvJEerZSnBaEDjNIyOafaQLtpQBhnCDa</pass_ticket><isgrayscale>1</isgrayscale></error> ticket_dict = xml_parse(ru.text) session['ticket_dict'] = ticket_dict result['code'] = 200 return jsonify(result)

    获取头像201,登录认证200

    <body>
        <div style=" 200px;margin: 0 auto;">
            <h1 style="text-align: center;">扫码登录</h1>
            <img id="userAvatar" style=" 200px;height: 200px;" src="https://login.weixin.qq.com/qrcode/{{qcode}}" alt="">
        </div>
    
        <script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js"></script>
        <script>
            $(function () {
                checkLogin();
            });
            function checkLogin() {
                $.ajax({
                    url:'/check/login',
                    method:'GET',
                    dataType:'json',
                    success:function (arg) {
                        console.log(arg);
                        checkLogin();
                        if(arg.code === 408){
                            checkLogin();
                        }else if(arg.code === 201){
                            $('#userAvatar').attr('src',arg.avatar);
                            checkLogin();
                        }else if(arg.code === 200){
                            location.href = "/index"
                        }
                    }
                })
            }
        </script>
    </body>

    3. 检查登录:确认登录
      同上
    4. 获取凭证:redirect_uri
      同上

    """
    import re
    data = 'window.QRLogin.code = 200; window.QRLogin.uuid = "gb8UuMBZyA==";'
    ret = re.findall('uuid = "(.*)";',data)[0]
    print(ret)
    """
    
    from bs4 import BeautifulSoup
    
    def xml_parse(text):
        result = {}
        soup = BeautifulSoup(text,'html.parser')
        tag_list = soup.find(name='error').find_all()
        for tag in tag_list:
            result[tag.name] = tag.text
        return result
    
    v = "<error><ret>0</ret><message></message><skey>@crypt_ac8812af_0ffde1190007c7c044bc31ae51407c45</skey><wxsid>fRwfacRtjRFpEIwt</wxsid><wxuin>1062220661</wxuin><pass_ticket>0M1plebTzNQ%2FKaSIfTfk65laCSXUWmjpxvJEerZSnBaEDjNIyOafaQLtpQBhnCDa</pass_ticket><isgrayscale>1</isgrayscale></error>"
    result = xml_parse(v)
    
    # print(result)
    
    print(round(1.4))

    5. 信息初始化:
    - 联系人
    - 公众号

    6. 获取所有联系人

    @app.route('/index')
    def index():
        pass_ticket = session['ticket_dict']['pass_ticket']
        init_url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=-979112921&lang=zh_CN&pass_ticket={0}".format(pass_ticket)
    
        rep = requests.post(
            url=init_url,
            json={
                'BaseRequest':{
                    'DeviceID':"e700290354098676",
                    'Sid':session['ticket_dict']['wxsid'],
                    'Skey':session['ticket_dict']['skey'],
                    'Uin':session['ticket_dict']['wxuin'],
                }
            }
        )
        rep.encoding = 'utf-8'
    
        init_user_dict = rep.json()
        print(init_user_dict)
    
        return render_template('index.html',init_user_dict=init_user_dict)

    index.html

    <body>
        <h1>欢迎使用Web微信:{{init_user_dict.User.NickName}}</h1>
    
        <h3>最近联系人</h3>
        <ul>
            {% for row in init_user_dict.ContactList %}
                <li>{{row.NickName}}</li>
            {% endfor %}
            <li><a href="#">查看所有联系人</a></li>
        </ul>
    
        <h3>最近公众号</h3>
        {% for item in init_user_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>

    7. 获取联系人列表

    1、

    @app.route('/contact/list')
    def contack_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
        # GET
        ctime = int(time.time() * 1000)
        pass_ticket = session['ticket_dict']['pass_ticket']
        skey = session['ticket_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['ticket_cookies']
        )
        res.encoding = 'utf-8'
        user_list = res.json()
    
        return render_template('contact_list.html',user_list=user_list)

    contact_list.html

    <body>
        <h1>联系人列表</h1>
        <ul>
            {% for user in user_list.MemberList %}
                <li>
                    <img style="height: 50px; 50px;" src="/get_img?prev={{user.HeadImgUrl}}">
                    <span>用户名:{{user.NickName}} 唯一标识:{{user.UserName}}</span>
                </li>
            {% endfor %}
    
        </ul>
    </body>

    在获取用户图片

    @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['ticket_cookies']
        )
    
        return rep.content

    8. 发送消息

    @app.route('/send/msg',methods=['GET','POST'])
    def send_msg():
        if request.method == "GET":
            return render_template('send_msg.html')
    
        ctime = int(time.time() * 1000)
        from_user = request.form.get('fromUser')
        to_user = request.form.get('toUser')
        content = request.form.get('content')
    
        data_dict = {
            'BaseRequest':{
                    'DeviceID':"e700290354098676",
                    'Sid':session['ticket_dict']['wxsid'],
                    'Skey':session['ticket_dict']['skey'],
                    'Uin':session['ticket_dict']['wxuin'],
            },
            'Msg':{
                'ClientMsgId':ctime,
                'Content':content,
                'FromUserName':from_user,
                'LocalID':ctime,
                'ToUserName':to_user,
                'Type':1
            },
            'Scene':0
        }
    
        msg_url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?lang=zh_CN&pass_ticket={0}".format(session['ticket_dict']['pass_ticket'])
        rep = requests.post(
            url=msg_url,
            data=bytes(json.dumps(data_dict,ensure_ascii=False),encoding='utf-8')
        )
    
        print(rep)
    
        return "发送成功"

    send_msg.html

    @app.route('/send/msg',methods=['GET','POST'])
    def send_msg():
        if request.method == "GET":
            return render_template('send_msg.html')
    
        ctime = int(time.time() * 1000)
        from_user = request.form.get('fromUser')
        to_user = request.form.get('toUser')
        content = request.form.get('content')
    
        data_dict = {
            'BaseRequest':{
                    'DeviceID':"e700290354098676",
                    'Sid':session['ticket_dict']['wxsid'],
                    'Skey':session['ticket_dict']['skey'],
                    'Uin':session['ticket_dict']['wxuin'],
            },
            'Msg':{
                'ClientMsgId':ctime,
                'Content':content,
                'FromUserName':from_user,
                'LocalID':ctime,
                'ToUserName':to_user,
                'Type':1
            },
            'Scene':0
        }
    
        msg_url = "https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?lang=zh_CN&pass_ticket={0}".format(session['ticket_dict']['pass_ticket'])
        rep = requests.post(
            url=msg_url,
            data=bytes(json.dumps(data_dict,ensure_ascii=False),encoding='utf-8')
        )
    
        print(rep)
    
        return "发送成功"

    9、使用

      使用发送信息的时候、需要先获取用户当前的UserName,在第一次获取index.html时

     print(init_user_dict)里去网页json解析出来即可使用,注意每次登录的username里的符号都会变化
    
    'User': {
    'Uin': 2589030507,
    'UserName': '@586d71fe149ae1942bc5bca1f64edd87d385b449850bdc6796ade1a92c9d2933',

    10、总结

    发送data和json的区别

        关系发送消息:
                data:
                    request.post(
                        url='xx',
                        data={'k1':'v1,'k2':'v2'}
                    )
                    #数据:  POST /  http1.1
    ....
    
    k1=v1&k2=v2
                    
                    
                    request.post(
                        url='xx',
                        data=json.dumps({'k1':'v1,'k2':'v2'})
                    )
                    #数据:  POST /  http1.1
    ....
    
    {'k1':'v1,'k2':'v2'}
                    
                    request.post(
                        url='xx',
                        data=b'asdfasdf'
                    )
                    #数据:  POST /  http1.1
    ....
    
    'asdfasdf'
                json:
                    request.post(
                        url='xx',
                        json={'k1':'v1,'k2':'v2'}
                    )
                    #数据:  POST /  http1.1
    Content-type:application/json....
    
    {'k1':'v1,'k2':'v2'}
        
                问题:
                    同时:POST请求发数据
                    
                    django:获取不到值?request.POST 
                    
                    发送数据格式:
                        方式一:
                            request.post(
                                url='xx',
                                data={'k1':'v1,'k2':'v2'}
                            )
                            #数据:  POST /  http1.1
    Content-type:urlencode-form.......
    
    k1=v1&k2=v2
            
                            
                            request.POST必然可以获取到值。
                                - content-type: urlencode-form
                                - 数据格式:k1=v1&k2=v2
        
                        方式二:
                            request.post(
                                url='xx',
                                json={'k1':'v1,'k2':'v2'}
                            )
                            #数据:  POST /  http1.1
    Content-type:application/json....
    
    {'k1':'v1,'k2':'v2'}
                            request.body 
                                字节 = {'k1':'v1,'k2':'v2'}
                                字节转换字符串
                                反序列化字符串 -> 字典 
                            
                            request.POST必然不可以获取到值。
                                - content-type: urlencode-form
                                - 数据格式:k1=v1&k2=v2
                            
                    
                知识点:
                    chrome->
                        Form Data:
                            phone=861513125555&password=12312312312&oneMonth=1
                            
                            reqeusts.post(
                                url=url,
                                data={
                                    phone:123123123123,
                                    password:asdfasdf
                                }
                            )
                        
                        Request Payload:
                            {"BaseRequest":{"Uin":981579400,"Sid":"zWvteTWqBop4heoT","Skey":"@crypt_2ccf8ab9_a710cf413c932e201987599558063c8e","DeviceID":"e358217921593270"},"Msg":{"Type":1,"Content":"test","FromUserName":"@60eef3f2d212721fda0aae891115aa7a","ToUserName":"@@6a5403f510a3192454ed1afebd78ec6033d5057c9038d7b943b201f0a74987d4","LocalID":"15300708105840758","ClientMsgId":"15300708105840758"},"Scene":0}
                        
                            reqeusts.post(
                                url=url,
                                json={
                                    phone:123123123123,
                                    password:asdfasdf
                                }
                            )
                            
                            reqeusts.post(
                                url=url,
                                data=bytes(json.dumps({
                                    phone:123123123123,
                                    password:asdfasdf
                                }),encoding=utf-8)
                            )
        
        
                    firefox:
                        表单数据:
                            
                        JSON:
                            
        
        
            目标:练习分析Http请求能力
  • 相关阅读:
    D:yyyUNetSegmentation_code_20180301data rain
    第六课cnn和迁移学习-七月在线-cv
    lecture7图像检索-七月在线-cv
    lecture4特征提取-七月在线-cv
    guling code细节
    resNet代码-小象/cv
    unet网络讲解,附代码
    数字三角形
    递归折半查找
    分治法寻找第k大的数
  • 原文地址:https://www.cnblogs.com/di2wu/p/10292348.html
Copyright © 2011-2022 走看看