第三百六十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索功能

Django实现搜索功能

1、在Django配置搜索结果页的路由映射

"""pachong URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see:https://docs.djangoproject.com/en/1.10/topics/http/urls/
Examples:
Function views1. Add an import:  from my_app import views2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views1. Add an import:  from other_app.views import Home2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf1. Import the include() function: from django.conf.urls import url, include2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app1 import viewsurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^$', views.indexluoji),url(r'^index/', views.indexluoji),url(r'^suggest/$', views.suggestluoji,name="suggest"),     # 搜索字段补全请求url(r'^search/$', views.searchluoji,name="search"),     # 搜索]

2、编写逻辑处理函数

在逻辑处理函数里实现搜索数据

(1)获取到用户的搜索词

(2)利用原生的elasticsearch(搜索引擎)接口,实现搜索,注明:elasticsearch-dsl就是在原生的elasticsearch上做了封装

Elasticsearch()方法,连接原生的elasticsearch服务器

search()方法,原生elasticsearch查询方法,支持原生的elasticsearch查询语句,返回的原生语句结果也就是字典形式的数据

在查询语句里进行关键词高亮处理

将查询到的结果,循环获取到后返回到html页面

from django.shortcuts import render# Create your views here.
from django.shortcuts import render,HttpResponse
from django.views.generic.base import View
from app1.models import lagouType               # 导入操作elasticsearch(搜索引擎)类
import json
from elasticsearch import Elasticsearch         # 导入原生的elasticsearch(搜索引擎)接口
client = Elasticsearch(hosts=["127.0.0.1"])     # 连接原生的elasticsearchdef indexluoji(request):print(request.method)  # 获取用户请求的路径return render(request, 'index.html')def suggestluoji(request):                                      # 搜索自动补全逻辑处理key_words = request.GET.get('s', '')                        # 获取到请求词re_datas = []if key_words:s = lagouType.search()                                  # 实例化elasticsearch(搜索引擎)类的search查询s = s.suggest('my_suggest', key_words, completion={"field": "suggest", "fuzzy": {"fuzziness": 1},"size": 5})suggestions = s.execute_suggest()for match in suggestions.my_suggest[0].options:source = match._sourcere_datas.append(source["title"])return HttpResponse(json.dumps(re_datas), content_type="application/json")def searchluoji(request):                                       # 搜索逻辑处理key_words = request.GET.get('q', '')                        # 获取到请求词response = client.search(                                   # 原生的elasticsearch接口的search()方法,就是搜索,可以支持原生elasticsearch语句查询index="lagou",                                          # 设置索引名称doc_type="biao",                                        # 设置表名称body={                                                  # 书写elasticsearch语句"query": {"multi_match": {                                # multi_match查询"query": key_words,                         # 查询关键词"fields": ["title", "description"]          # 查询字段}},"from": 0,                                          # 从第几条开始获取"size": 10,                                         # 获取多少条数据"highlight": {                                      # 查询关键词高亮处理"pre_tags": ['<span class="keyWord">'],         # 高亮开始标签"post_tags": ['</span>'],                       # 高亮结束标签"fields": {                                     # 高亮设置"title": {},                                # 高亮字段"description": {}                           # 高亮字段}}})total_nums = response["hits"]["total"]                      # 获取查询结果的总条数hit_list = []                                               # 设置一个列表来储存搜索到的信息,返回给html页面for hit in response["hits"]["hits"]:                        # 循环查询到的结果hit_dict = {}                                           # 设置一个字典来储存循环结果if "title" in hit["highlight"]:                         # 判断title字段,如果高亮字段有类容hit_dict["title"] = "".join(hit["highlight"]["title"])      # 获取高亮里的titleelse:hit_dict["title"] = hit["_source"]["title"]                 # 否则获取不是高亮里的titleif "description" in hit["highlight"]:                           # 判断description字段,如果高亮字段有类容hit_dict["description"] = "".join(hit["highlight"]["description"])[:500]    # 获取高亮里的descriptionelse:hit_dict["description"] = hit["_source"]["description"]     # 否则获取不是高亮里的descriptionhit_dict["url"] = hit["_source"]["url"]                         # 获取返回urlhit_list.append(hit_dict)                                       # 将获取到内容的字典,添加到列表return render(request, 'result.html', {"all_hits": hit_list, "key_words": key_words})       #显示页面和将列表和搜索词返回到html

3、html页面接收搜索结果

注意:因为Django实现了防止恶意代码写入,凡是通过变量传输到html页面的html类型代码,将会被自动转换成字符串方式显示,索引我们需要在接收变量的字段用:{% autoescape off %} {{ 接收变量 }} {% endautoescape %},来显示html代码,

搜索后因为进行了一次跳转,所以搜索框里的搜索词将不存在,我们需要在传递搜索结果到页面的时候,将搜索词也传递进来填充到搜索框

<!DOCTYPE html >
<html xmlns="http://www.w3.org/1999/xhtml">
{#引入静态文件路径#}
{% load staticfiles %}
<head>
<meta http-equiv="X-UA-Compatible" content="IE=emulateIE7" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>python-lcv-search搜索引擎</title>
<link href="{% static 'css/style.css'%}" rel="stylesheet" type="text/css" />
<link href="{% static 'css/result.css'%}" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="container"><div id="hd" class="ue-clear"><a href="/"><div class="logo"></div></a><div class="inputArea"><input type="text" class="searchInput" value="{{ key_words }}"/><input type="button" class="searchButton" onclick="add_search()"/></div></div><div class="nav"><ul class="searchList"><li class="searchItem current" data-type="article">文章</li><li class="searchItem" data-type="question">问答</li><li class="searchItem" data-type="job">职位</li></ul></div><div id="bd" class="ue-clear"><div id="main"><div class="sideBar"><div class="subfield">网站</div><ul class="subfieldContext"><li><span class="name">伯乐在线</span><span class="unit">(None)</span></li><li><span class="name">知乎</span><span class="unit">(9862)</span></li><li><span class="name">拉勾网</span><span class="unit">(9862)</span></li><li class="more"><a href="javascript:;"><span class="text">更多</span><i class="moreIcon"></i></a></li></ul><div class="sideBarShowHide"><a href="javascript:;" class="icon"></a></div></div><div class="resultArea"><p class="resultTotal"><span class="info">找到约&nbsp;<span class="totalResult">45</span>&nbsp;条结果(用时<span class="time">0.643128</span>秒),共约<span class="totalPage">5</span>页</span></p><div class="resultList">{% for hit in all_hits %}<div class="resultItem"><div class="itemHead"><a href="{% autoescape off %} {{ hit.url }} {% endautoescape %}"  target="_blank" class="title">{% autoescape off %} {{ hit.title }} {% endautoescape %}</a><span class="divsion">-</span><span class="fileType"><span class="label">来源:</span><span class="value">网络</span></span><span class="dependValue"><span class="label">得分:</span><span class="value">3.401155</span></span></div><div class="itemBody">{% autoescape off %} {{ hit.description }} {% endautoescape %}</div></div>{% endfor %}</div><!-- 分页 --><div class="pagination ue-clear"></div><!-- 相关搜索 --></div><div class="historyArea"><div class="hotSearch"><h6>热门搜索</h6><ul class="historyList"><li><a href="/search?q=linux">linux</a></li></ul></div><div class="mySearch"><h6>我的搜索</h6><ul class="historyList"></ul></div></div></div><!-- End of main --></div><!--End of bd-->
</div><div id="foot">Copyright &copy;projectsedu.com 版权所有  E-mail:admin@projectsedu.com</div>
</body>
<script type="text/javascript" src="{% static 'js/jquery.js'%}"></script>
<script type="text/javascript" src="{% static 'js/global.js'%}"></script>
<script type="text/javascript" src="{% static 'js/pagination.js'%}"></script>
<script type="text/javascript">var search_url = "/search/"$('.searchList').on('click', '.searchItem', function(){$('.searchList .searchItem').removeClass('current');$(this).addClass('current');    });$.each($('.subfieldContext'), function(i, item){$(this).find('li:gt(2)').hide().end().find('li:last').show();        });function removeByValue(arr, val) {for(var i=0; i<arr.length; i++) {if(arr[i] == val) {arr.splice(i, 1);break;}}}$('.subfieldContext .more').click(function(e){var $more = $(this).parent('.subfieldContext').find('.more');if($more.hasClass('show')){if($(this).hasClass('define')){$(this).parent('.subfieldContext').find('.more').removeClass('show').find('.text').text('自定义');}else{$(this).parent('.subfieldContext').find('.more').removeClass('show').find('.text').text('更多');    }$(this).parent('.subfieldContext').find('li:gt(2)').hide().end().find('li:last').show();}else{$(this).parent('.subfieldContext').find('.more').addClass('show').find('.text').text('收起');$(this).parent('.subfieldContext').find('li:gt(2)').show();    }});$('.sideBarShowHide a').click(function(e) {if($('#main').hasClass('sideBarHide')){$('#main').removeClass('sideBarHide');$('#container').removeClass('sideBarHide');}else{$('#main').addClass('sideBarHide');    $('#container').addClass('sideBarHide');}});var key_words = "java"//分页$(".pagination").pagination(45, {current_page :0, //当前页码items_per_page :10,display_msg :true,callback :pageselectCallback});function pageselectCallback(page_id, jq) {window.location.href=search_url+'?q='+key_words+'&p='+page_id}setHeight();$(window).resize(function(){setHeight();    });function setHeight(){if($('#container').outerHeight() < $(window).height()){$('#container').height($(window).height()-33);}    }
</script>
<script type="text/javascript">$('.searchList').on('click', '.searchItem', function(){$('.searchList .searchItem').removeClass('current');$(this).addClass('current');});// 联想下拉显示隐藏$('.searchInput').on('focus', function(){$('.dataList').show()});// 联想下拉点击$('.dataList').on('click', 'li', function(){var text = $(this).text();$('.searchInput').val(text);$('.dataList').hide()});hideElement($('.dataList'), $('.searchInput'));
</script>
<script>var searchArr;//定义一个search的,判断浏览器有无数据存储(搜索历史)if(localStorage.search){//如果有,转换成 数组的形式存放到searchArr的数组里(localStorage以字符串的形式存储,所以要把它转换成数组的形式)searchArr= localStorage.search.split(",")}else{//如果没有,则定义searchArr为一个空的数组searchArr = [];}//把存储的数据显示出来作为搜索历史MapSearchArr();function add_search(){var val = $(".searchInput").val();if (val.length>=2){//点击搜索按钮时,去重KillRepeat(val);//去重后把数组存储到浏览器localStoragelocalStorage.search = searchArr;//然后再把搜索内容显示出来MapSearchArr();}window.location.href=search_url+'?q='+val+"&s_type="+$(".searchItem.current").attr('data-type')}function MapSearchArr(){var tmpHtml = "";var arrLen = 0if (searchArr.length > 6){arrLen = 6}else {arrLen = searchArr.length}for (var i=0;i<arrLen;i++){tmpHtml += '<li><a href="/search?q='+searchArr[i]+'">'+searchArr[i]+'</a></li>'}$(".mySearch .historyList").append(tmpHtml);}//去重function KillRepeat(val){var kill = 0;for (var i=0;i<searchArr.length;i++){if(val===searchArr[i]){kill ++;}}if(kill<1){searchArr.unshift(val);}else {removeByValue(searchArr, val)searchArr.unshift(val)}}
</script>
</html>

最终效果

学习python-day02-25---转自Python分布式爬虫打造搜索引擎Scrapy精讲相关推荐

  1. 学习python-day02-24---转自Python分布式爬虫打造搜索引擎Scrapy精讲

    第三百六十八节,Python分布式爬虫打造搜索引擎Scrapy精讲-用Django实现搜索的自动补全功能 elasticsearch(搜索引擎)提供了自动补全接口 官方说明:https://www.e ...

  2. 第三百三十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—深度优先与广度优先原理...

    第三百三十八节,Python分布式爬虫打造搜索引擎Scrapy精讲-深度优先与广度优先原理 网站树形结构 深度优先 是从左到右深度进行爬取的,以深度为准则从左到右的执行(递归方式实现)Scrapy默认 ...

  3. 第三百六十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)基本的索引和文档CRUD操作、增、删、改、查...

    第三百六十二节,Python分布式爬虫打造搜索引擎Scrapy精讲-elasticsearch(搜索引擎)基本的索引和文档CRUD操作.增.删.改.查 elasticsearch(搜索引擎)基本的索引 ...

  4. 三十七 Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中...

    Python分布式爬虫打造搜索引擎Scrapy精讲-将bloomfilter(布隆过滤器)集成到scrapy-redis中,判断URL是否重复 布隆过滤器(Bloom Filter)详解 基本概念 如 ...

  5. 第三百六十节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的基本概念...

    第三百六十节,Python分布式爬虫打造搜索引擎Scrapy精讲-elasticsearch(搜索引擎)的基本概念 elasticsearch的基本概念 1.集群:一个或者多个节点组织在一起 2.节点 ...

  6. 第三百四十五节,Python分布式爬虫打造搜索引擎Scrapy精讲—爬虫和反爬的对抗过程以及策略—scrapy架构源码分析图...

    第三百四十五节,Python分布式爬虫打造搜索引擎Scrapy精讲-爬虫和反爬的对抗过程以及策略-scrapy架构源码分析图 1.基本概念 2.反爬虫的目的 3.爬虫和反爬的对抗过程以及策略 scra ...

  7. 三十五 Python分布式爬虫打造搜索引擎Scrapy精讲—scrapy分布式爬虫要点

    1.分布式爬虫原理 2.分布式爬虫优点 3.分布式爬虫需要解决的问题 转载于:https://www.cnblogs.com/meng-wei-zhi/p/8182813.html

  8. 学习python-day01-13---转自Python分布式爬虫打造搜索引擎Scrapy精讲

    第三百三十六节,web爬虫讲解2-urllib库中使用xpath表达式-BeautifulSoup基础 在urllib中,我们一样可以使用xpath表达式进行信息提取,此时,你需要首先安装lxml模块 ...

  9. 学习python-day01-01---转自Python分布式爬虫打造搜索引擎Scrapy精讲

    第三百二十四节,web爬虫,scrapy模块介绍与使用 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中. 其最初是为 ...

最新文章

  1. jQuery中的text()、html()和val()以及innerText、innerHTML和value
  2. proftpd java_Proftpd:编译安装
  3. python3 整除_python如何整除
  4. 如何构建 HBase 集群监控系统?
  5. java中未解决的编译问题_java – 我遇到了这个异常:未解决的编译问题
  6. Mac屏幕常亮时间控制:Theine
  7. MongoDB 数据集合导出 与 导入
  8. 计算机写程序的步骤,电脑怎么编程 电脑编程的方法
  9. SAP:SMARTFORM打开WORD文档出错,或无法编辑
  10. canvas卡通兔子萝卜飞行动画
  11. 电源防反接电路 供电自动切换电路 - MOS管体二极管的应用
  12. 创建表 编码_创建没有编码的专业商业网站
  13. 微信添加表情提示过大怎么解决?GIF太大怎么变小?
  14. 优化之Joiner组件
  15. [iOS]UIButton/UIImageView导圆角设边框
  16. 永恩上线服务器维护,LOL网友爆料:劫将推出至臻皮肤,卢锡安赛娜情侣皮肤即将上线?...
  17. wifi安全模式是什么_WIFI的完整形式是什么?
  18. 我的公众号 - 豆芽儿 软件研发人才生长社区
  19. 使用pandas对行和列进行交换
  20. 自杀和抑郁症是为了进化?

热门文章

  1. ubuntu VCS+verdi安装教程
  2. Java网课基础笔记(31)19-08-13
  3. 汽车电子控制-汽油机电子控制QA(1)
  4. 怎么查看拼多多店铺销量?怎么查看店铺后台数据图?
  5. 安卓期末大作业——售票APP源码和设计报告
  6. cesium获取当前层级
  7. 美国访问学者生活之行-开车租车及停车
  8. home credit default risk(捷信违约风险)机器学习模型复现(论文_毕业设计_作业)
  9. 21年 河海大学 计算机科学与技术(838) 学硕 上岸心得
  10. java 引用数据类型Scanner类 Random类