Flask+Bootstrap展示MM图片在网页上,从而更好地挑选富婆??

Flask+Bootstrap展示MM图片在网页上,从而更好地挑选富婆??

前言

  • 哎呀呀,好久没更新博客了,趁着今天是1024节,我们的节日,来庆祝一下吧,祝各位大佬节日快乐呀~~
  • 今年的程序员节可真是特殊的一年呢:2020-1024=996
  • 言归正传,本次的分享是基于我前面两篇博客的,这篇已经是第三篇啦,小伙伴们可以按顺序观看更佳哦,(获取数据-分析数据-展示数据)这个完整项目算是收尾了:
  1. 【Scrapy学习心得】爬虫实战五(Scrapy-Redis分布式爬虫)
  2. pyechart可视化分析有缘网18岁以上女性的相关信息(单身狗请进~)

需求分析

我想要的展示MM图片的一个效果是这样的:每个MM的昵称、年龄、城市、颜值分数和座右铭以及原来的交友网址放在一个卡片上,来展现在页面上,大概如下图:

但如果不加筛选条件,就算展现在网页上,也很难找到心仪的那个她呀。。于是我想增加几个筛选的条件,比如:年龄,城市以及最重要的颜值,大概如下图:

那么问题又来了,颜值我怎么知道呢,原始数据又没有给出,难道让我猜嘛??当然不是,我这里用到百度的一个人脸检测API,文档说明点击跳转,其中人脸检测的返回参数里面就有一个beauty参数,范围0-100,越大表示越美,这个就是颜值了。

开始敲代码

1.编写前端html

首先编写我们的html,因为本篇文章用到的是Bootstrap前端框架的一些组件,文档说明点击跳转,本文没有下载Bootstrap的源码,而是直接通过cdn来引入:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>

三个筛选条件的表单代码:

<form class="needs-validation" action="/" method="POST">
    <div class="form-row">
    <div class="col-md-3 mb-3">
      <select name="age" class="custom-select" id="age">
        <option selected disabled value="">请选择年龄区间:</option>
        <option value="18-25">18岁~25岁</option>
        <option value="26-30">26岁~30岁</option>
        <option value="31-40">31岁~40岁</option>
        <option value="41-50">41岁~50岁</option>
        <option value="51-100">51岁以上</option>
      </select>
    </div>
    <div class="col-md-3 mb-3">
      <select name="face" class="custom-select" id="face">
        <option selected disabled value="">请选择颜值区间:</option>
        <option value="80-100">80分以上</option>
        <option value="60-80">60分~80分</option>
        <option value="40-60">40分~60分</option>
        <option value="30-40">30分~40分</option>
        <option value="0-20">20分以下</option>
      </select>
    </div>
      <div class="col-md-3 mb-3">
      <select name="area" class="custom-select" id="area">
        <option selected disabled value="">请选择地区:</option>
        <option value="广东">广东省</option>
        <option value="四川">四川省</option>
        <option value="湖南">湖南省</option>
        <option value="湖北">湖北省</option>
        <option value="广西">广西省</option>
      </select>
    </div>
      <button style="height:38px" type="submit" class="btn btn-outline-primary">查询</button>
    </div>
</form>

从后端获取的图片等数据并展现在小卡片上的代码如下:

<div class="row row-cols-1 row-cols-md-3">
      {% for item in data %}
      <div class="col mb-4">
        <div class="card h-100">
          <img src="data:;base64,{{ item.get('img')}}" class="card-img-top" alt="...">
          <div class="card-body">
            <p class="h5">{{ item.get('name')}}&nbsp;&nbsp;{{ item.get('age')}}岁&nbsp;&nbsp;{{ item.get('area')}}&nbsp;&nbsp;P{{ item.get('how') }}&nbsp;&nbsp;{{ item.get('score') }}分</p>
            <p class="card-text">座右铭:{{ item.get('content')}}</p><br>
            <a href="{{ item.get('url') }}" class="btn btn-primary" target="_blank">详细资料</a>
          </div>
        </div>
      </div>
      {% endfor %}
</div>

2.编写Python后端

如果一个查询里面数据太多,请求的时间就会变得非常慢,针对这个问题,采用了分页查询,从而提高请求的速度,在app.py文件中写了两个路由,第一个路由函数即下面是处理第一次筛选条件的请求:

@app.route('/',methods=['POST','GET'])
def index():
    '''
    num:控制分页查询
    formdata:记录表单内容,使得下一页的请求是上一次的表单
    flag:控制下一页按钮的显现或隐藏
    '''
    global num,formdata,flag
    if request.method == 'POST':
        num=0
        flag=False
        formdata=request.form
        db=Mysql(formdata.get('age'),formdata.get('face'),formdata.get('area'),num)
        count,data=db.get_items()
        if count == 20:
            num=1
            flag=True
        else:
            flag = False
        result=[]
        if count != 0:
            for i in data:
                name,address,age,image,url,motto,score=i
                image=image.split(',') if image is not None else []
                if image != []:
                    for how,each in enumerate(image):
                        with open(each,'rb') as f:
                            img = base64.b64encode(f.read()).decode('utf-8')
                            result.append({'name':name,'age':age,'area':address,'img':img,'content':motto,'url':url,'how':how+1,'score':score})
            db.db_close()
            return render_template('index.html',data=result,flag=flag)
        else:
            return render_template('index.html',flag=flag)
    else:
        flag=False
        return render_template('index.html',flag=flag)

第二个路由函数是接收并处理下一页请求的:

@app.route('/next',methods=['GET'])
def next():
    global num,flag
    if formdata is not None:
        db=Mysql(formdata.get('age'),formdata.get('face'),formdata.get('area'),num)
        count, data = db.get_items()
        if count == 20:
            num+=1
        else:
            flag=False
        result = []
        if count != 0:
            for i in data:
                name, address, age, image, url, motto, score= i
                image = image.split(',') if image is not None else []
                if image != []:
                    for how,each in enumerate(image):
                        with open(each, 'rb') as f:
                            img = base64.b64encode(f.read()).decode('utf-8')
                            result.append({'name': name, 'age': age, 'area': address, 'img': img, 'content': motto, 'url': url,'how':how+1,'score':score})
            db.db_close()
            return render_template('index.html', data=result,flag=flag)
        else:
            return render_template('index.html',flag=flag)
    else:
        return render_template('index.html',flag=flag)

最后,接收前端页面发送的筛选条件,查询数据库中对应的数据并返回给前端,mysql.py文件的代码如下:

import pymysql

class Mysql(object):
    def __init__(self,age,face,area,num):
        self.conn = pymysql.connect(host='localhost',user='',password='',database='',charset="utf8")
        self.cursor = self.conn.cursor()  # 游标对象
        self.age=[int(i) for i in age.split('-')] if age is not None else None
        self.face=[int(i) for i in face.split('-')] if face is not None else None
        self.area=area
        self.num=num

    def get_items(self):
        sql = 'select name,address,age,img_path,url,motto,score from youyuan where'
        if self.age is not None: #是否筛选了年龄
            sql+=f' age between {self.age[0]} and {self.age[1]} and'
        if self.face is not None: #是否筛选了颜值
            sql+=f' score between {self.face[0]} and {self.face[1]} and'
        if self.area is not None: #是否筛选了地区
            sql+=f' address like "{self.area}%" and'
        if sql != 'select name,address,age,img_path,url,motto,score from youyuan where':
            self.cursor.execute(sql[:-4]+f' limit {self.num*20},20')
            data=self.cursor.fetchall()
            return len(data),data
        else:
            self.cursor.execute(sql[:-6] + f' limit {self.num*20},20')
            data = self.cursor.fetchall()
            return len(data), data

    def db_close(self):
        self.cursor.close()
        self.conn.close()

结果展示

运行程序之后,打开浏览器输入:http://127.0.0.1:5000,选择年龄、颜值和城市之后,点击查询,即可查到对应的MM信息,之后就可以愉快地寻找富婆啦~

录屏是真的难弄,把视频转换成gif,然而上传图片的大小不能超过5MB,于是我只能调快了播放倍速,看着好像有点闪眼哈哈哈哈哈嗝~

不足的地方

  • 使用百度的API来得到颜值的分数,虽然个人感觉API的审美还算可以,并且还是无限次数调用,但是免费的QPS实在太低,试过用多线程去请求获取图片的颜值,请求太快会拿不到数据,最终还是慢慢地去调用,真的太卑微了,幸好图片也不是很多吧,6000+条记录,大概有10000张图片。
  • 由于前端的知识不够,导致页面太过于简陋,只有几个简单的按钮,想弄那种高大上的弄不出来。。。以后再研究研究吧,功能到位了就行,其实我的要求并不高哈哈~
  • 还有就是Flask的知识也不够全面,很多模块应该是有现成的,我硬是自己来实现了哈哈!感觉在重复造轮子,后面需要再全面地去了解和使用Flask才行。

ps:这个项目的完整代码,我已经全部整理了一遍,关注【Python王者之路】公众号,留言回复20201024,即可获取下载链接。(你的关注就是我最大的动力!)


写在最后

工作实在是太忙了,根本没时间去弄别的东西呀!!感觉我已经嗅到了“社畜”的味道了。
不过,我一有时间,还是会继续更新下去的,继续去探索未知~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值