ElasticSearch仿京东搜索

一:爬取京东数据

package com.esjd.Utils;import lombok.SneakyThrows;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;import java.net.MalformedURLException;
import java.net.URL;public class HtmlParseUtil {@SneakyThrowspublic static void main(String[] args)   {//获取请求 https://search.jd.com/Search?keyword=java 需要联网String url = "https://search.jd.com/Search?keyword=java";//解析网页 jsoup返回的 Document就是游览器 Document对象Document document = Jsoup.parse(new URL(url),30000);//获取网页idJ_goodsListElement element = document.getElementById("J_goodsList");System.out.println(element.html());//获取所有的li元素Elements elements = document.getElementsByTag("li");for (Element element1 : elements) {String img = element1.getElementsByTag("img").eq(0).attr("data-lazy-img");String price = element1.getElementsByClass("p-price").eq(0).text();String title = element1.getElementsByClass("p-name").eq(0).text();System.out.println("______________________________________--");System.out.println(img);System.out.println(price);System.out.println(title);}}
}
封装成工具类
@SneakyThrows
public List<Content> paresJD(String keyword){//获取请求 https://search.jd.com/Search?keyword=java 需要联网String urlKeywords = URLEncoder.encode(keyword, "UTF-8");//获取请求 https://search.jd.com/Search?keyword=java//前提: 需要联网, 而且不能获取到AJAX!String url ="https://search.jd.com/Search?keyword=" + urlKeywords + "&enc=utf-8";//解析网页 jsoup返回的 Document就是游览器 Document对象Document document = Jsoup.parse(new URL(url),30000);//获取网页idJ_goodsListElement element = document.getElementById("J_goodsList");//System.out.println(element.html());//获取所有的li元素Elements elements = document.getElementsByTag("li");ArrayList<Content>  goodsList = new ArrayList<>();for (Element element1 : elements) {if (element1.attr("class").equalsIgnoreCase("gl-item")) {String img = element1.getElementsByTag("img").eq(0).attr("data-lazy-img");String price = element1.getElementsByClass("p-price").eq(0).text();String title = element1.getElementsByClass("p-name").eq(0).text();Content content = new Content();content.setTitle(title);content.setPrice(price);content.setImg(img);goodsList.add(content);}}return goodsList;
}
编写pojo类
@Data
@AllArgsConstructor
@NoArgsConstructorpublic class Content {//根据业务需求自己添加属性private  String title;private String img;private String price;}
解析数据到es中
  @Autowired
//  不能直接使用     @Autowired 需要spring容器private RestHighLevelClient restHighLevelClient;//解析数据放入es中public Boolean  parseContent(String keywords) throws IOException {List<Content> contents = new HtmlParseUtil().paresJD(keywords);//把查询的数据放入es中BulkRequest bulkRequest = new BulkRequest();bulkRequest.timeout("2m");for (int i = 0; i < contents.size(); i++) {System.out.println(JSON.toJSONString(contents.get(i)));bulkRequest.add(new IndexRequest("jd_goods").source(JSON.toJSONString(contents.get(i)), XContentType.JSON));}BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);//判断返回是否成功return  !bulk.hasFailures();}}
对应的controller接口
@Autowired
private  ContentService contentService;//爬取数据到es中
@GetMapping("/pares/{keyword}")
public Boolean pares(@PathVariable("keyword") String  keyword) throws IOException{return  contentService.parseContent(keyword);
}
二:前后端分离进行搜索实现

搜索实现和搜索高亮实现

新建前端模板进行请求接口编写

new Vue({el:"#app",data:{keyword: '',results: []},methods:{searchKey(){var keyword = this.keyword;console.log(keyword);//搜索分页// axios.get("search/"+keyword+"/1/10").then(response =>{//     console.log(response);//     //绑定数据//     this.results = response.data;// })//实现搜索高亮axios.get("/HighlightBuilder/"+keyword+"/1/10").then(response =>{console.log(response);//绑定数据this.results = response.data;})}}
})
编写service层
  //2. 获取这些数据实现搜索功能public List<Map<String ,Object>> searchPage(String keyword ,int  pageNo,int pageSize) throws IOException {if(pageNo<=1){pageNo = 1;}//条件搜索SearchRequest searchRequest = new SearchRequest("jd_goods");SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//分页sourceBuilder.from(pageNo);sourceBuilder.size(pageSize);//精准匹配TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", keyword);sourceBuilder.query(termQueryBuilder);sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));//执行搜索searchRequest.source(sourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//解析结果ArrayList<Map<String,Object>> list = new ArrayList<>();for (SearchHit documentFields : searchResponse.getHits().getHits()) {//把所有结果遍历出来然后封装到list集合里面list.add( documentFields.getSourceAsMap());}return  list;}//2. 获取这些数据实现搜索高亮功能public List<Map<String ,Object>> searchHighlightBuilder(String keyword ,int  pageNo,int pageSize) throws IOException {if(pageNo<=1){pageNo = 1;}//条件搜索SearchRequest searchRequest = new SearchRequest("jd_goods");SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//分页sourceBuilder.from(pageNo);sourceBuilder.size(pageSize);//精准匹配TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", keyword);sourceBuilder.query(termQueryBuilder);sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));//高亮HighlightBuilder highlightBuilder = new HighlightBuilder();//设置标题高亮highlightBuilder.field("title");//关闭多个高亮字段显示//highlightBuilder.requireFieldMatch(true);//设置高亮样式highlightBuilder.preTags("<span style='color:red'>");highlightBuilder.postTags("</span>");sourceBuilder.highlighter(highlightBuilder);//执行搜索searchRequest.source(sourceBuilder);SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);//解析结果ArrayList<Map<String,Object>> list = new ArrayList<>();for (SearchHit hit : searchResponse.getHits().getHits()) {//解析高亮的字段Map<String, HighlightField> highlightFields = hit.getHighlightFields();//获取标题HighlightField title = highlightFields.get("title");//原来的结果Map<String, Object> sourceAsMap = hit.getSourceAsMap();//解析高亮字段 把原先的字段替换为高亮字段if (title!= null){Text[] fragments = title.fragments();StringBuilder n_title = new StringBuilder();for (Text text : fragments) {n_title.append(text);}sourceAsMap.put("title", n_title.toString());}
//            if (title!= null){
//                Text[] fragments = title.fragments();
//                String n_title = "";
//                for (Text text : fragments) {
//                    n_title+= text;
//                }
//                sourceAsMap.put("title",n_title);
//
//
//            }//把所有结果遍历出来然后封装到list集合里面list.add(sourceAsMap);}return  list;}
实现的接口controller
//对数据进行分页
@GetMapping("/search/{keyword}/{pageNo}/{pageSize}")
public List<Map<String,Object>> search(@PathVariable("keyword") String keyword,@PathVariable("pageNo") int pageNo,@PathVariable("pageSize")int pageSize) throws IOException {return  contentService.searchPage(keyword, pageNo, pageSize);
}//高亮
@GetMapping("HighlightBuilder/{keyword}/{pageNo}/{pageSize}")
public List<Map<String,Object>> searchHighlightBuilder(@PathVariable("keyword") String keyword,@PathVariable("pageNo") int pageNo,@PathVariable("pageSize")int pageSize) throws IOException {return  contentService.searchHighlightBuilder(keyword, pageNo, pageSize);
}

null){
Text[] fragments = title.fragments();
StringBuilder n_title = new StringBuilder();
for (Text text : fragments) {
n_title.append(text);
}
sourceAsMap.put(“title”, n_title.toString());

        }

// if (title!= null){
// Text[] fragments = title.fragments();
// String n_title = “”;
// for (Text text : fragments) {
// n_title+= text;
// }
// sourceAsMap.put(“title”,n_title);
//
//
// }

        //把所有结果遍历出来然后封装到list集合里面list.add(sourceAsMap);}return  list;
}

#### 实现的接口controller

//对数据进行分页
@GetMapping(“/search/{keyword}/{pageNo}/{pageSize}”)
public List<Map<String,Object>> search(@PathVariable(“keyword”) String keyword,
@PathVariable(“pageNo”) int pageNo,
@PathVariable(“pageSize”)int pageSize) throws IOException {

return  contentService.searchPage(keyword, pageNo, pageSize);

}

//高亮
@GetMapping(“HighlightBuilder/{keyword}/{pageNo}/{pageSize}”)
public List<Map<String,Object>> searchHighlightBuilder(@PathVariable(“keyword”) String keyword,
@PathVariable(“pageNo”) int pageNo,
@PathVariable(“pageSize”)int pageSize) throws IOException {

return  contentService.searchHighlightBuilder(keyword, pageNo, pageSize);

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/710249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux的条件变量

条件变量 条件变量本身不是锁&#xff0c;但是它可以造成线程阻塞。通常于互斥锁配合使用。给多线程提供一个会和的场合。 使用互斥量保护共享数据使用条件变量可以造成线程阻塞&#xff0c;等待某个条件的发生&#xff0c;当条件满足的时候解除阻塞。 条件变量的两个动作&a…

python 基础知识点(蓝桥杯python科目个人复习计划55)

今日复习内容&#xff1a;做题 例题1&#xff1a;体育健将 问题描述&#xff1a; 小蓝作为班级里的体育健将&#xff0c;他被安排在校运会时参加n个体育项目&#xff0c;第i个体育项目参赛需要耗时ai分钟&#xff0c;赛后休息需要bi分钟&#xff08;这意味着当他参加完这场比…

【AIGC大模型】InstantID 赏析

论文地址&#xff1a;https://arxiv.org/abs/2401.07519 InstantID 主页&#xff1a;https://instantid.github.io/ Demo &#xff1a;https://huggingface.co/spaces/InstantX/InstantID code&#xff1a; InstantID/InstantID: InstantID : Zero-shot Identity-Preserving…

计算机组成原理-第一/二章 概述和数据的表示和运算【期末复习|考研复习】

文章目录 前言第一章 计算机组成原理 概述及各种码1.1 计算机硬件的基本组成1.1.1 存储器1.1.2 运算器1.1.3 控制器 1.2 计算机的工作过程1.3 计算机的性能指标1.4 各个字长区别与联系 第二章 数据的表示与运算2.1 ASCII码2.2 各种码2.3 浮点数 总结 前言 给大家整理了一下计算…

网络安全与代理技术:解密 SOCKS5、代理IP 和 HTTP

在当今数字化的世界中&#xff0c;网络安全问题备受关注。作为网络安全的重要组成部分&#xff0c;代理技术在保护个人隐私和网络安全方面发挥着关键作用。本文将以教授的身份&#xff0c;简明扼要地介绍 SOCKS5 代理、代理IP、HTTP 代理等关键词&#xff0c;帮助读者了解这些技…

雅特力AT32L021首款低功耗MCU震撼登场

雅特力于2月28日正式发布AT32L021首款入门级低功耗MCU&#xff0c;搭配不同容量Flash、SRAM&#xff0c;提供7种封装类型共21个型号选择&#xff0c;最小封装面积仅3x3mm。为降低能耗&#xff0c;延长设备运作时间&#xff0c;AT32L021系列支持多种能耗模式和休眠模式&#xff…

spark中dataframe起别名对join过程的影响

toDF().as("a").join(df2,Seq("seq1"),"right") .filter($"a.seq1".isNotNull)toDF().as("a").join(df2,Seq("seq1"),"right") .filter($"seq1".isNotNull)今天之前我认为这里不应该用别名&a…

2.29文件IO-进程 作业

1.要求将当前路径下&#xff0c;所有文件的权限及最后一次的访问时间提取出来&#xff0c;写入到file.txt中! !提示: opendir readir stat-->提取出来的数据写入到file.xt中 #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include &l…

详解kubernetes中的Pod生命周期

目录 1.1 Pod生命周期概述 1.2 创建和终止 1.2.1 Pod的创建过程 1.2.2 Pod的终止过程 1.3 初始化容器 1.3.1 案例 1.4 容器探测 1.4.1 Exec示例 1.5 重启策略 1.1 Pod生命周期概述 Pod中的生命周期主要包含以下过程&#xff1a; pod创建过程 运行初始化容器&#xff…

Mysql Day07

存储过程 -- 存储过程基本语法 -- 创建 create procedure p1() begin select count(*) from student; end; -- 调用 call p1(); -- 查看 select * from information_schema.ROUTINES where ROUTINE_SCHEMA itcast; show create procedure p1; -- 删除 drop procedure if exis…

weak 的实现原理

iOS 在运行时维护着一个全局的弱引用表&#xff0c;该表是一个 hash 表&#xff0c;hash表的 key 是 weak 对象的地址&#xff0c;value 是指向该对象的所有 weak 指针的地址数组。 /**全局的弱引用表&#xff0c;本质是一个hash结构&#xff0c;object作为key, weak_entry_…

npm 设置取消代理

npm 设置淘宝镜像源&#xff1a;npm install -g cnpm --registryhttps://registry.npm.taobao.org npm 查看当前配置信息 npm config listnpm 设置代理 npm config set proxy 127.0.0.1:7890 npm config set https-proxy 127.0.0.1:7890删除代理信息 npm config delete pro…

TCP/UDP模型:2024/2/29

作业1&#xff1a;TCP模型 服务器端&#xff1a; #include <myhead.h> #define SER_IP "192.168.199.129" #define SER_PORT 8899int main(int argc, const char *argv[]) {//1.创建用于连接的套接字文件int sfdsocket(AF_INET,SOCK_STREAM,0);if(sfd-1){per…

【蓝桥杯】赢球票(模拟、枚举、搜索)

一.题目描述 某机构举办球票大奖赛。获奖选手有机会赢得若干张球票。 主持人拿出 N 张卡片&#xff08;上面写着 1~N 的数字&#xff09;&#xff0c;打乱顺序&#xff0c;排成一个圆圈。你可以从任意一张 卡片开始顺时针数数: 1,2,3..... 如果数到的数字刚好和卡片上的数字…

深入理解nginx的https alpn机制

目录 1. 概述2. alpn协议的简要理解2.1 ssl的握手过程2.2 通过抓包看一下alpn的细节3. nginx源码分析3.1 给ssl上下文设置alpn回调3.2 连接初始化3.3 处理alpn协议回调3.4 握手完成,启用http协议4.4 总结阅读姊妹篇:深入理解nginx的https alpn机制 1. 概述 应用层协议协商(…

基于Siamese网络的zero-shot意图分类

原文地址&#xff1a;Zero-Shot Intent Classification with Siamese Networks 通过零样本意图分类有效定位域外意图 2021 年 9 月 24 日 意图识别是面向目标对话系统的一项重要任务。意图识别(有时也称为意图检测)是使用标签对每个用户话语进行分类的任务&#xff0c;该标签…

Shell:字符串的截取和替换

#/bin/sha="hello, world, 88"echo ${a:0}echo ${a:2:3}echo ${a/l/ii}echo ${a//l/ii}echo ${a#he}echo ${a#*,}echo ${a##*,}echo ${a%88}echo ${a%,*}echo ${a%%,*} 运行程序输出: hello, world, 88 llo heiilo, world, 88 heiiiio, woriid, 88 llo, world, 88 w…

网络编程学习

思维导图 代码练习 TCP实现通信 服务器端代码 #include <myhead.h> #define SER_IP "192.168.152.135" #define SER_PORT 8910 int main(int argc, const char *argv[]) {//&#xff11;创建用于监听的套接字int sfd -1;sfd socket(AF_INET,SOCK_STREAM,0)…

【mysql】 1819 - Your password does not satisfy the current policy requirements

创建mysql账户密码时候提示&#xff1a; 1819 - Your password does not satisfy the current policy requirements 1819-您的密码不符合当前策略要求 下面是执行的sql DROP DATABASE IF EXISTS company;CREATE DATABASE company CHARACTER SET utf8mb4 ;grant all on com…

VuePress + GitHub 搭建个人博客踩坑记录

最近想给我教练搭个网站,本来选的是 VuePress 框架,也折腾完了,起码是搭建出来了,踩的坑也都总结好了 但是最近发现了一个更简洁的模板: VuePress-theme-hope ,所以最终网站使用的样式是这个 不过我觉得这里面踩坑的记录应该还是有些价值的,分享出来,看看能不能帮到一些小伙伴~…