python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > es flask分页+高亮

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

作者:General_zy

本文主要介绍了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接口的理解。

到此这篇关于es+flask搜索小项目实现分页+高亮的示例代码的文章就介绍到这了,更多相关es flask分页+高亮内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文