• Python-S9-Day123——爬虫两示例


    • 01 今日内容回顾

    • 02 内容回顾和补充:面向对象约束

    • 03 爬虫之抽屉新热榜

    • 04 爬虫之抽屉自动登录(一)

    • 05 爬虫之抽屉自动登录(二)

    • 06 爬虫之登录github(一)

    • 07 爬虫之登录github(二)

    • 08 爬虫之登录拉钩

    • 09 上述内容总结

    • 10 requests模块详解(一)

    • 11 requests模块详解(二)

    • 12 requests模块详解(三)

    • 13 bs4模块简述

    • 14 9期最丑的男人:轮询

    • 15 9期最丑的男人:长轮询

    • 16 今日总结

    01 今日内容回顾

    1.1 requests;

    1.2 bs4(一定是bs4版本);

    1.3 轮询/长轮询(消息队列相关知识);

    02 内容回顾和补充:面向对象约束

    2.1 Flask上下文管理机制;

    2.2 为什么要使用上下文管理机制呢?

    2.3 为什么要用Local呢?

    2.4 LocalStack维护成栈

    2.5 视图函数中使用:request/session/g/current_app

    2.6 请求上下文和应用上下文要先放到local中才能使用;

    2.7 离线脚本;

    2.8 面向对象的认知;

      2.8.1编程范式——面向对象和面向过程;

    2.9 约束;

      2.9.1 Java和C#中的接口:约定子类中必须包含某个方法;

      2.9.2 抽象方法/抽象类:约束子类中必须包含某个方法;

      2.9.3 Python没有接口,但是有抽象方法、抽象类(ABC实现);

      2.9.4 Python中类的约束是以类的继承+raise NotImplementedError来伪造抽象类;

      2.9.5 告知他人如何使用,自己开发时候,如何使用呢?约束别人写代码的时候,遵循规范标准;

    03 爬虫之抽屉新热榜

    3.1 博文参考;

    https://www.cnblogs.com/wupeiqi/articles/6283017.html

    3.2 requests模拟浏览器请求,bs4解析字符串;

    3.3 爬取抽屉新热榜;

    import requests
    from bs4 import BeautifulSoup
    
    ###########################示例1:爬出数据(携带请求头)################################
    r1 = requests.get(
        url="https://dig.chouti.com/",
        headers={
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36'
        }
    )
    soup = BeautifulSoup(r1.text, 'html.parser')
    # 标签对象;
    content_list = soup.find(name='div', id='content-list')
    # [标签对象,标签对象]
    item_list = content_list.find_all(name='div', attrs={'class': 'item'})
    for item in item_list:
        a = item.find(name='a', attrs={'class': 'show-content color-chag'})
        print(a.text.strip())

     

    /Users/cuixiaozhao/PycharmProjects/s9/s9day123/venv/bin/python /Users/cuixiaozhao/PycharmProjects/s9/s9day123/爬取抽屉新热榜.py
    【段子】    
                                                        
                                                                                                            
                                                        感人
    《只狼 影逝二度》公布主视觉图(图5),明年3月22日,是朋友就来跟我死两次!
    马云明年交棒张勇,阿里巴巴低开2.3%
    两部门:加强网约车和顺风车平台驾驶员背景核查;整改完成前,滴滴等平台无限期停止顺风车服务
    是个狠人!
    @金融圈女神经:在房产群里看到一个拷问灵魂的问题:假设你在上海中环内有套90平米的老破小,夫妻二人35-40岁,税后合计三四万(月薪),家有幼儿,父母在外地,你会选择:1.吃好喝好穿好,小孩上私立,偶尔出趟国?还是2.节衣缩食,置换一套大房子或者买二套?不讨论2016年,也不讨论2020年,只讨论此时此刻。​​​
    【目击者还原网红殴打孕妇:她说这种孕妇生下来的小孩也不是什么好种】9月7日,浙江杭州,杨女士称,自己怀孕32周被网红@Saya一(陈某伊)打骂致先兆早产,打人者在微博上拥有300多万粉丝。杨女士称,当晚她看到一只没牵绳的法斗犬朝自己扑来,丈夫用脚推了狗一下,陈某伊便与自己和丈夫发生争执,期间还辱骂自己并动手。
    肉肉女孩,ins:juasicko
    那些游戏报错画面中隐藏的“游戏”
    房企销售宣传的惯用套路,目瞪口呆!
    【高盛解读:如何看待中国消费放缓】高盛认为,非官方统计的中国消费数据相对官方口径更加悲观,是因为前者并未考虑到消费者的消费习惯正由线下转向线上。在高盛看来,中国商品消费疲软的“罪魁祸首”是消费信贷增长放缓和债务负担进一步走高。
    腾讯投资并购部回应“投资子弹短信”:未提及投资事宜,只曾在微信上有简短沟通
    2018维密名单公布:何穗、陈瑜复试通过,奚梦瑶免试保送
    【全球首个海洋垃圾系统下海,背后的 Ocean Cleanup 创始人仅24岁】Boyan Slat 是荷兰人,16岁在希腊潜水的时候,发现海洋里的塑料比鱼多,回国后就开始研究海洋垃圾。17岁在TEDx演讲,讲述自己创新的洋流垃圾收集系统。19岁便成立公司,专注实现自己清理海洋垃圾的梦想。
    【段子】    
                                                        
                                                                                                            
                                                        看了一个神剧的剧本,看到一半就看不下去了,女主要过检查站传递绝密信息,既要带信息过去又不能被鬼子看出来,特工队领导教她密码技术,在竹篮那编不同色块的竹篾,劳资一看妈的这不就是二维码技术吗,这已经不是神剧的问题了,这是瞎几把乱编的问题,万一鬼子同时摸出条码枪怎么办,很气愤,乱写(@神嘛事儿)
    北京高校化粪池爆炸污染水源致学生腹泻?校方否认
    2018年的俄罗斯产共党
    【网秦创始人林宇发文称遭董事长史文勇绑架 受到非人折磨】今日,网秦发布公告,任命网秦创始人林宇接任网秦CEO,并担任联席董事长。林宇还在朋友圈晒出《立案告知书》照片,并发文称自己遭原网秦董事长史文勇绑架,期间受到非人折磨,九死一生。​​​​​
    韩春雨被曝早年自称代笔博士论文收费七千,还欲让学生买论文
    生日快乐鸭!两只鸭鸭迎来了它们的2岁生日,铲屎官劈了半个大西瓜,用青瓜当蜡烛,用苹果做了个“2”给它们庆生
    【91岁教师守候留守儿童:只要我有口气,不会让他们念不起书】91岁的叶老师教英语已经40年了,退休后他自费办“留守儿童之家”,为留守儿童无偿补课18年,至今仍坚持上课、批改作业。他说:”我愿意我的最后一口气,是在讲台上呼出去的。”
    没学历的男朋友送外卖我该不该和他分手?
    当我试图帮助别人……
    【百度回应“搜索品牌官网、公立医院问题”】当网民使用百度搜索时,如遭遇搜索推广结果中因假冒、钓鱼欺诈等网站受到损失,只要提供相关证据,百度将不设上限进行“全额”先行保障。
    【侍魂归来、名越稔洋带来新作,Playstation直播活动信息汇总】索尼Playstation LineUp Tour已经结束,活动上出现了很多令人激动的新游戏。《侍魂》新作、名越稔洋的《Judge Eyes 死神遗言》、《铳墓》新作、《噬神者3》等等。
    
    Process finished with exit code 

    04 爬虫之抽屉自动登录(一)

    2.1 登录爬取;

    import requests
    from bs4 import BeautifulSoup
    
    ###########################示例1:爬出数据(携带请求头)################################
    r1 = requests.get(
        url="https://dig.chouti.com/",
        headers={
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36'
        }
    )
    soup = BeautifulSoup(r1.text, 'html.parser')
    # 标签对象;
    content_list = soup.find(name='div', id='content-list')
    # [标签对象,标签对象]
    item_list = content_list.find_all(name='div', attrs={'class': 'item'})
    for item in item_list:
        a = item.find(name='a', attrs={'class': 'show-content color-chag'})
        print(a.text.strip())

    2.2 点赞(反爬虫验证); 

    ###########################示例2:点赞(携带请求头)################################
    # 1. 查看首页;
    import requests
    
    r1 = requests.get(
        url='https://dig.chouti.com/',
        headers={
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36'
        }
    )
    print(r1.cookies)
    # 2. 提交用户名和密码, 发送post请求;
    r2 = requests.post(
        url='https://dig.chouti.com/login',
        headers={
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36'
        },
        data={
            'phone': '8613811221893 ',
            'password': '19930911cxs.',
            'oneMonth': 1
        },
        cookies=r1.cookies.get_dict()
    )
    print(r2.text)  # {"result":{"code":"9999", "message":"", "data":{"complateReg":"0","destJid":"ctu_52518370025"}}}
    print("拿到抽屉网站返回的cookies",
          r2.cookies.get_dict())  # 拿到抽屉网站返回的cookies {'gpsd': '4f535c2cce5ff030aeb4a2d2e94816b1', 'puid': 'a5308883c2de1e61b40dc7ddb850d385', 'JSESSIONID': 'aaajHz9vNpOEMdfzWjYww'}
    
    # 3. 进行点赞;
    r3 = requests.post(
        url='https://dig.chouti.com/link/vote?linksId=22010751',
        headers={
            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36'
        },
        cookies=r1.cookies.get_dict()
    )
    print(r3.text)  # {"result":{"code":"30010", "message":"你已经推荐过了", "data":""}}

    05 爬虫之抽屉自动登录(二)

    06 爬虫之登录github(一)

    #######################示例三:自动登录github#########################################
    # 1、GET:登录访问页面;
    ""
    '''
    - 去HTML中找到隐藏的input标签,获取类似于csrf_token;
    - 获取cookie;
    '''
    # 2、发送post请求,用户名和密码;
    '''
    - 发送数据;
        -csrf;
        -用户名;
        -密码;
    - 携带cookie
    '''
    
    # 3、GET,访问https://github.com/settings/emails
    '''
    - 携带cookie
    '''

    07 爬虫之登录github(二)

    08 爬虫之登录拉钩

    8.1 Referer头,是上一次请求的地址,可用于做图片防盗链;

    import requests
    import re
    
    r1 = requests.get(
        url='https://passport.lagou.com/login/login.html',
        headers={
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36',
    
        },
    )
    X_Anti_Forge_Token = re.findall("X_Anti_Forge_Token = '(.*?)'", r1.text, re.S)[0]
    X_Anti_Forge_Code = re.findall("X_Anti_Forge_Code = '(.*?)'", r1.text, re.S)[0]
    #print(X_Anti_Forge_Token, X_Anti_Forge_Code)
    # print(r1.text)
    
    r2 = requests.post(
        url='https://passport.lagou.com/login/login.json',
        headers={
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36',
            'X-Anit-Forge-Code': X_Anti_Forge_Code,
            'X-Anit-Forge-Token': X_Anti_Forge_Token,
            'X-Request-With': 'XMLHttpRequest',
            'Referer': 'https://passport.lagou.com/login/login.html',
        },
        data={
            'isValidate': True,
            'username': '13811221893',
            'password': '69de96af1d1ed394c2b9dafc5f441a60',
            'request_form_verifyCode': ' ',
            'submit': '',
        },
        cookies = r1.cookies.get_dict()
    )
    print(r2.text)
    '''
    {"content":{"rows":[]},"message":"操作成功","state":1,"submitCode":87998714,"submitToken":"6dc215ff-4476-42b2-b3aa-e84e5a14cae5"}
    '''

    09 上述内容总结

    s9day123 
    
    内容回顾:
        第一部分:Flask
            1. flask上下文管理机制
    
                切记:不要说详细
            2. Local的作用?
            
            3. LocalStack维护成栈
            
            4. 视图函数中使用:request/session/g/current_app
                
                注意:请求上下文和应用上下文需要先放入Local中,才能获取到。
                    # by luffycity.com
    
                    from flask import Flask,current_app,request,session,g
    
    
                    app = Flask(__name__)
    
                    # 错误
                    # print(current_app.config)
    
                    @app.route('/index')
                    def index():
                        # 正确
                        print(current_app.config)
                        
                        return "Index"
    
                    if __name__ == '__main__':
                        app.run()
    
            5. 离线脚本
            
                from chun import db,create_app
                from flask import current_app
    
                # 错误
                # print(current_app.config)
    
                # app = create_app()
                # app_ctx = app.app_context()
                # with app_ctx:
                #     # 正确
                #     print(current_app.config)
        
        第二部分:面向对象
            1. 谈谈你对面向对象的认识。
            
            2. 约束 
                Java: 
                    - 接口,约子类中必须包含某个方法(约束)。
                        Interface IMessage:
                            def func1(self):
                                pass 
                            def func2(self):
                                pass 
                                
                        class Msg(IMessage):
                            def func1(self):
                                print('func1') 
                            def func2(self):
                                print('func1') 
                    
                    - 抽象方法/抽象类,约子类中必须包含某个方法。(约束+继承)
                        class abstract IMessage:
                            def abstract func1(self):
                                pass 
                            def abstract func2(self):
                                pass 
                            
                            def func3(self):
                                print('asdfasdf') 
                                
                        class Msg(IMessage):
                            def func1(self):
                                print('func1') 
                            def func2(self):
                                print('func1') 
                
                Python:
                    - 接口(无)
                    - 抽象方法/抽象类(有,ABC)
                    
                    - 类继承+异常
                        
                        class IMessage(object):
    
                            def func1(self):
                                raise NotImplementedError('子类没有实现func1方法')
    
    
                        class Msg(IMessage):
                            def func1(self):
                                print('123')
    
    
                        obj = Msg()
                        obj.func1()
                        
                有什么用?用于告知其他人以后继承时,需要实现那个方法,如:
                    
                    class BaseAuthentication(object):
                        """
                        All authentication classes should extend BaseAuthentication.
                        """
    
                        def authenticate(self, request):
                            """
                            Authenticate the request and return a two-tuple of (user, token).
                            """
                            raise NotImplementedError(".authenticate() must be overridden.")
    
                        def authenticate_header(self, request):
                            """
                            Return a string to be used as the value of the `WWW-Authenticate`
                            header in a `401 Unauthenticated` response, or `None` if the
                            authentication scheme should return `403 Permission Denied` responses.
                            """
                            pass
    
                
                以后自己开发时,如何使用?
                    需求:
                        class BaseMessage(object):
    
                            def send(self):
                                raise NotImplementedError('必须实现send方法')
    
    
                        class Msg(BaseMessage):
                            def send(self):
                                print('发送短信')
    
    
                        class Wechat(BaseMessage):
                            def send(self):
                                print('发送微信')
    
    
                        class Email(BaseMessage):
                            def send(self):
                                print('发送邮件')
    
    
    
                        class DingDing(BaseMessage):
                            def send(self):
                                print('发送钉钉提醒')
                    
                
            3. __dict__
            
            4. metaclass 
        
                
                
                
        整理面试题(今天交给我)
            
                
                
    今日内容:
        - 爬虫
            - requests
            - bs4
        - 长轮询/轮询
        
        
    内容详细:
        参考博客:https://www.cnblogs.com/wupeiqi/articles/6283017.html
        
        需求: 
            1. 爬取汽车之家新闻咨询
                - 什么都不带
            2. 爬抽屉新热榜
                - 带请求头
                - 带cookie
                - 登录:
                    - 获取cookie
                    - 登录:携带cookie做授权
                    - 带cookie去访问
            3. 爬取GitHub
                - 带请求头
                - 带cookie
                - 请求体中:
                    commit:Sign in
                    utf8:✓
                    authenticity_token:hmGj4oS9ryOrcwoxK83raFqKR4sFG1yC09NxnDJg3B/ycUvCNZFPs4AxTsd8yPbm1F3i38WlPHPcRGQtyR0mmw==
                    login:asdfasdfasdf
                    password:woshiniba8
            
            4. 登录拉勾网 
                - 密码加密
                    - 找js,通过python实现加密方式
                    - 找密文,密码<=>密文
                
                - Referer头, 上一次请求地址,可以用于做防盗链。
            
        总结:
            请求头:
                user-agent
                referer
                host
                cookie
                特殊请起头,查看上一次请求获取内容。
                    'X-Anit-Forge-Code':...
                    'X-Anit-Forge-Token':...
            请求体:
                - 原始数据
                - 原始数据 + token
                - 密文
                    - 找算法 
                    - 使用密文
                    
            套路:
                - post登录获取cookie,以后携带cookie 
                - get获取未授权cookie,post登录携带cookie去授权,以后携带cookie 
            
                    
        
        1. requests模块 
            - 方法
                requests.get
                requests.post 
                requests.put 
                requests.delete 
                ...
                requests.request(method='POST')
            
            - 参数
            
            - session 
                session = requests.Session()
                
                session.get()
                session.post()
                
                ...
        
            
        2. BeautifulSoup
        
        3. 轮询/长轮询(跟爬虫没有关系)
            在线投票:最丑的男人
            
            - 轮询:每2秒钟发送请求。
            - 长轮询:最多hang住30s(兼容性好)
                - 实时
                - 在线 
            - websocket实现(兼容性不太好)
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        
        
        
        
        
        
        
        

    10 requests模块详解(一)

    10.1 方法:

    • requests.get
    • requests.post
    • requests.put
    • requests.delete

    10.2 参数;

    requests.get = 

    • url = 'https://www.cuixiaozhao.com'
    • headers = {}
    • cookies = {}
    • params = {'k1':'v1','k2':'v2'} #https://www.cuixiaozhao.com?k1=v1&k2=v2

    requests.post = 

    • url = 'https://www.cuixiaozhao.com'
    • headers = {}
    • cookies = {}
    • params = {'k1':'v1','k2':'v2'} #https://www.cuixiaozhao.com?k1=v1&k2=v2
    • data = {}

    10.3 参数;

    10.3.1 url;

    10.3.2 headers;

    10.3.3 cookies;

    10.3.4 params;

    10.3.5 data;

    10.3.6 data传请求体;

    10.3.7 json传请求体;

    10.3.8 代理,代理池;

    10.3.9 文件上传;

    10.3.10 用户认证auth;

    • 内部用户名和密码,用户名和密码加密后,放在请求头中传给后台;
    • "用户名:密码"
    • base64("用户名:密码")
    • "Basic base64(“用户名:密码”)"
    • 请求头:Authorzation:“basic base64(“用户名:密码”)”
    from requests.auth import HTTPBasicAuth, HTTPDigestAuth
    
    ret = requests.get(
        'https://api.github.com/user', auth=HTTPBasicAuth('admin', 'admin')
    )
    print(ret.text)

    11 requests模块详解(二)

    12 requests模块详解(三)

    12.1 超时(timeout);

    12.2 允许重定向allow_redirects;

    12.3 大文件下载stream,一点一点去下载,防止占满内存空间;

    12.4 证书cert——百度、腾讯不用携带证书(系统帮我们做了);

    12.5 确认verify;类似于yum install 中的-y参数;

    13 bs4模块简述

    13.1 方法;

    13.2 参数;

    13.3 session,但是推荐自己带上session;

    13.4 长轮询;

    14 9期最丑的男人:轮询

    14.1 轮询/长轮询(跟爬虫没有关系)

    • 轮询:每隔固定时间发送一次请求,比如每隔2秒钟;
    • 长轮询:夯住一段时间,间隔较长时间进行发送请求,比如1分钟;省去了socket连接的时间;在线实时,一般就是长轮询好!

    app.py

    from flask import Flask, render_template, request, jsonify
    
    app = Flask(__name__)
    
    USERS = {
        '1': {'name': '贝贝', 'count': 1},
        '2': {'name': '小东北', 'count': 0},
        '3': {'name': '何伟明', 'count': 0},
    }
    
    
    @app.route('/user/list')
    def user_list():
        import time
        # time.sleep(120)
        return render_template('user_list.html', users=USERS)
    
    
    @app.route('/vote', methods=['POST'])
    def vote():
        uid = request.form.get('uid')
        USERS[uid]['count'] += 1
        return '投票成功!'
    
        
    @app.route('/get/vote')
    def get_vote():
        return jsonify(USERS)
    
    
    if __name__ == '__main__':
        app.run(host="192.168.1.49", threaded=True)

    app1.py

    from flask import Flask, render_template, request, jsonify
    
    app = Flask(__name__)
    import queue
    
    q = queue.Queue()
    
    
    @app.route('/get/vote')
    def get_vote():
        try:
            val = q.get(timeout=5)
        except queue.Empty:
            val = "已超时"
        return val
    
    
    @app.route('/vote')
    def vote():
        q.put('10')
        return "投票成功!"
    
    
    if __name__ == '__main__':
        app.run(threaded=True)

    user_list.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js"></script>
        <style>
            li {
                cursor: pointer;
            }
        </style>
    </head>
    <body>
    <ul id="userlist">
        {% for key,val in users.items() %}
        <li uid="{{key}}">{{val.name}} ({{val.count}})</li>
        {% endfor %}
    </ul>
    
    <script>
        $(function () {
            $('#userlist').on('dblclick', 'li', function () {
                var uid = $(this).attr('uid');
                $.ajax({
                    url: '/vote',
                    type: 'POST',
                    data: {uid: uid},
                    success: function (arg) {
                        console.log(arg);
                    }
                });
            });
        });
    
        /*
        获取投票信息;
        */
        function get_vote() {
            $.ajax({
                url: '/get/vote',
                type: 'GET',
                dataType: 'JSON',
                success: function (arg) {
                    console.log(arg);
                    $('#userlist').empty();
                    $.each(arg, function (k, v) {
                        console.log(k, v);
                        var li = document.createElement('li');
                        li.setAttribute('uid', k);
                        li.innerText = v.name + "(" + v.count + ")";
                        $('#userlist').append(li);
                    })
                }
            })
        }
    
        //设置定时器,2000ms = 2s;
        setInterval(get_vote, 2000)
    </script>
    </body>
    </html>

    15 9期最丑的男人:长轮询

    app.py;

    from flask import Flask, render_template, request, jsonify, session
    import uuid
    import queue
    
    app = Flask(__name__)
    app.secret_key = 'asdfasdfasd'
    
    USERS = {
        '1': {'name': '贝贝', 'count': 1},
        '2': {'name': '小东北', 'count': 0},
        '3': {'name': '何伟明', 'count': 0},
    }
    
    QUEQUE_DICT = {
        # 'asdfasdfasdfasdf':Queue()
    }
    
    
    @app.route('/user/list')
    def user_list():
        user_uuid = str(uuid.uuid4())
        QUEQUE_DICT[user_uuid] = queue.Queue()
    
        session['current_user_uuid'] = user_uuid
        return render_template('user_list.html', users=USERS)
    
    
    @app.route('/vote', methods=['POST'])
    def vote():
        uid = request.form.get('uid')
        USERS[uid]['count'] += 1
        for q in QUEQUE_DICT.values():
            q.put(USERS)
        return "投票成功"
    
    
    @app.route('/get/vote', methods=['GET'])
    def get_vote():
        user_uuid = session['current_user_uuid']
        q = QUEQUE_DICT[user_uuid]
    
        ret = {'status': True, 'data': None}
        try:
            users = q.get(timeout=5)
            ret['data'] = users
        except queue.Empty:
            ret['status'] = False
    
        return jsonify(ret)
    
    
    if __name__ == '__main__':
        app.run(threaded=True)
        # app.run(threaded=True)

    user_list.html

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <style>
            li {
                cursor: pointer;
            }
        </style>
    </head>
    <body>
    <ul id="userList">
        {% for key,val in users.items() %}
        <li uid="{{key}}">{{val.name}} ({{val.count}})</li>
        {% endfor %}
    </ul>
    
    <script src="https://cdn.bootcss.com/jquery/3.3.0/jquery.min.js"></script>
    <script>
    
        $(function () {
            $('#userList').on('click', 'li', function () {
                var uid = $(this).attr('uid');
                $.ajax({
                    url: '/vote',
                    type: 'POST',
                    data: {uid: uid},
                    success: function (arg) {
                        console.log(arg);
                    }
                })
            });
            get_vote();
        });
    
        /*
        获取投票信息
         */
        function get_vote() {
            $.ajax({
                url: '/get/vote',
                type: "GET",
                dataType: 'JSON',
                success: function (arg) {
                    if (arg.status) {
                        $('#userList').empty();
                        $.each(arg.data, function (k, v) {
                            var li = document.createElement('li');
                            li.setAttribute('uid', k);
                            li.innerText = v.name + "(" + v.count + ')';
                            $('#userList').append(li);
                        })
                    }
                    get_vote();
    
                }
            })
        }
    
    </script>
    </body>
    </html>

    16 今日总结

    16.1 轮询通过定时器实现;

    16.2 长轮询会将请求夯住,如果有信息过来,会立即返回,节省连接次数;

    16.3 适用场景:实时在线;

    16.4 websocket实现长轮询,但是兼容性不太好;

  • 相关阅读:
    cobbler default system 网络安装时主机的menu上只有一个local选项
    tcpdump使用方法
    cobbler 修改 distro_signatures.json
    wireshark in text mode: tshark
    Mac OSX使用隐藏文件夹
    sql中多条件进行排序的问题
    Linux查看打日志文件
    XML Parser Error on line 39: 必须声明元素类型 "domainObjectRenamingRule"。
    Access denied for user '密码'@'192.18.0.0' (using password: YES)
    springboot之DevTools热部署的简单原理解析
  • 原文地址:https://www.cnblogs.com/tqtl911/p/9623254.html
Copyright © 2020-2023  润新知