es+flask搜索小项目实现分页+高亮的示例代码

环境

  • 前端:html,css,js,jQuery,bootstrap
  • 后端:flask
  • 搜索引擎:elasticsearch
  • 数据源:某某之家

项目展示

es+flask搜索小项目实现分页+高亮的示例代码

es+flask搜索小项目实现分页+高亮的示例代码

项目目录

es+flask搜索小项目实现分页+高亮的示例代码

主要源码

获取数据源并写入es

from lxml import etree
from concurrent.futures import ThreadPoolExecutor
from elasticsearch import Elasticsearch
from elasticsearch import helpers
import requests

headers = {
    \'user-agent\': \'ua\'
}

es = Elasticsearch()
if not es.indices.exists(index=\'car\'):
    es.indices.create(index=\'car\', mappings={
        \'properties\': {
            \'url\': {
                \'type\': \'text\'
            },
            \'img\': {
                \'type\': \'text\'
            },
            \'title\': {
                \'type\': \'text\'
            },
            \'desc\': {
                \'type\': \'text\'
            }

        }
    })


def task(url,page):
    res = requests.get(url, headers)
    text = res.text
    tree = etree.HTML(text)
    ul_list = tree.xpath(\'//ul[@class=\"article\"]\')
    actions = []
    for ul in ul_list:
        li_list = ul.xpath(\'./li\')
        for li in li_list:
            url = li.xpath(\'./a/@href\'),
            img = li.xpath(\'./a/div/img/@src\'),
            desc = li.xpath(\'./a/p/text()\'),
            title = li.xpath(\'./a/h3/text()\')
            if title:
                doc = {
                    \'_index\': \'car\',
                    \'url\': f\'https:{url[0][0]}\',
                    \'img\': img[0][0],
                    \'desc\': desc[0][0],
                    \'title\': title[0],
                }
                actions.append(doc)
    helpers.bulk(es, actions=actions)
    print(f\'第{page}页完成!\')


def main():
    with ThreadPoolExecutor() as pool:
        for i in range(1, 11):
            url = f\'https://www.autohome.com.cn/all/{i}/\'
            pool.submit(task, url=url,page=i)


if __name__ == \'__main__\':
    main()

视图函数

from flask import Blueprint
from flask import request
from flask import render_template
from flask import jsonify
from web.ext import es
from pprint import pprint

search_bp = Blueprint(\'search\', __name__, url_prefix=\'/search\')


@search_bp.route(\'/\', methods=[\'get\', \'post\'])
def search():
    if request.method == \'GET\':
        return render_template(\'search.html\')
    elif request.method == \'POST\':
        content = request.values.get(\'content\')
        size = 10
        current = int(request.values.get(\'current\', \'0\'))
        if content:
            res = es.search(index=\'car\', query={
                \'match\': {
                    \"title\": content
                }
            }, highlight={
                \"pre_tags\": \"<span style=\'color: red\'>\"
                ,
                \"post_tags\": \"</span>\"
                ,
                \"fields\": {
                    \"title\": {}
                }
            }, size=1000)
        else:
            res = es.search(index=\'car\', query={
                \'match_all\': {}
            }, size=1000)
        new_res = res[\'hits\'][\'hits\']
        total = int(res[\'hits\'][\'total\'][\'value\'])
        need_page = (total // size) + 1
        data = {
            \'res\': new_res[current * size:current * size + size],
            \'need_page\': need_page,
            \'total\': total
        }
        return jsonify(data)

前端

<!DOCTYPE html>
<html lang=\"en\">
<head>
    <meta charset=\"UTF-8\">
    <title>General Search</title>
    <link rel=\"stylesheet\" href=\"{{ url_for(\'static\',filename=\'css/bootstrap.min.css\') }}\">
    <script src=\"{{ url_for(\'static\',filename=\'js/jQuery.js\') }}\"></script>
    <script src=\"{{ url_for(\'static\',filename=\'js/bootstrap.min.js\') }}\"></script>
    <style>
        .title{
            font-size: 25px;
            font-weight: 10;
        }
        .result{
            color: red;
        }
    </style>
</head>
<body>
<div>
    <nav class=\"navbar navbar-default\">
      <div class=\"container-fluid\">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class=\"navbar-header\">
          <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\"#bs-example-navbar-collapse-1\" aria-expanded=\"false\">
            <span class=\"sr-only\">Toggle navigation</span>
            <span class=\"icon-bar\"></span>
            <span class=\"icon-bar\"></span>
            <span class=\"icon-bar\"></span>
          </button>
          <a class=\"navbar-brand\" href=\"#\" style=\"margin-left: 100px\">General Search</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class=\"collapse navbar-collapse\" id=\"bs-example-navbar-collapse-1\">
          <ul class=\"nav navbar-nav\">
          </ul>
          <div class=\"navbar-form navbar-left\">
            <div class=\"form-group\">
              <input type=\"text\" class=\"form-control\" placeholder=\"\" id=\"content\" style=\"width: 800px;margin-left: 200px\">
            </div>
          </div>
            <button class=\"btn btn-primary pull-right\" id=\"submit\" style=\"margin-top: 8px;width: 100px;\">搜&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;索</button>
        </div><!-- /.navbar-collapse -->
      </div><!-- /.container-fluid -->
</nav>
</div>
<div class=\"container\">
    General为您找到相关结果约<span id=\'count\' class=\"result\">0</span>个
    <hr>
</div>
<div class=\"container\" id=\"tags\">
</div>
<div class=\"text-center\">
    <nav aria-label=\"Page navigation\">
      <ul class=\"pagination\" id=\"page\">
      </ul>
    </nav>
</div>
<script>


    function getData(current)
    {
        let content=$(\'#content\').val()
        let tags=$(\'#tags\')
        $(\'#count\').text()
        tags.empty()
        $.ajax({
            url:\"\",
            type:\'post\',
            data:{
                \'content\':content,
                \'current\':current
            },
            dataType:\'JSON\',
            success:function (res){
                let length=res.total
                let need_page=res.need_page
                $(\'#count\').text(length)
                $.each(res.res,function (index,value){
                    let source=value._source
                    let title=source.title
                    let highlight=value.highlight
                    if (highlight)
                    {
                        title=highlight.title
                    }
                    let div=`
                    <div>
                        <p><a href=\"${source.url}\" target=\"_blank\">
                        <span class=\"title\">${title}</span>
                        <br>
                        <img src=\"${source.img}\" alt=\"\">
                        </a></p>
                        <p>${source.desc}</p>
                        <hr>
                    </div>
                    `
                    tags.append(div)
                })
                $(\'#page\').empty()
                for(let i=0;i<need_page;i++)
                {
                    let tmp=i+1
                    if (current==i)
                    {
                        $(\'#page\').append(\'<li class=\"active\"><span class=\"changePage\">\'+tmp+\'</span></li>\')
                    }
                    else {
                        $(\'#page\').append(\'<li><span class=\"changePage\">\'+tmp+\'</span></li>\')
                    }

                }
            }
        })
    }
    $(\'#submit\').click(function (){
        getData(0)
    })

    $(\'#page\').on(\'click\',\'li\',function (){
        getData($(this).text()-1)
    })

</script>
</body>
</html>

app配置

from flask import Flask
from flask_session import Session
from web.ext import db
from .search.search import search_bp
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand


def create_app():
    app = Flask(__name__)
    app.config.from_object(\'settings.DevelopmentConfig\')
    app.register_blueprint(search_bp)
    Session(app)
    db.init_app(app)
    app = Manager(app)
    Migrate(app, db)
    app.add_command(\'db\', MigrateCommand)

    return app

总结

对比django,flask最后选用自由度较大的flask。

集合flask-script,flask_sqlalchemy,flask-migrate加快开发。

写一个小demo深化了对es接口的理解。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容