Java爬虫小测---ElasticSearch

项目搭建

1、启动ES,和head-master,用head-master建立索引

在这里插入图片描述
不建立也没事,添加数据的时候会自动创建

2、导入SpringBoot需要的依赖

注意:elasticsearch的版本要和自己本地的版本一致!所以还要在pom里面添加自定义版本
在这里插入图片描述

<!--解析网页需要的依赖Jsoup-->
<dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.10.2</version>
</dependency>
<!--阿里的JSon转换依赖-->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.73</version>
</dependency>
<!--ES启动依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!--thymeleaf模板依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--lombok依赖-->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>

3、项目用到的静态资源(修改过的)

  • 链接:https://pan.baidu.com/s/1X1kwMHsDvML-0rBEJnUOdA
  • 提取码:qjqy

4、添加SpringBoot配置(application.yml)

#端口改为9090
server:port: 9090# 关闭 thymeleaf 的缓存
spring:thymeleaf:cache: false

5、项目的整体结构

在这里插入图片描述

6、添加静态资源到项目中

在这里插入图片描述

7、SpringBoot中添加ES客户端配置类

ElasticSearchClientConfig.java

package com.wu.config;@Configuration
public class ElasticSearchClientConfig {@Beanpublic RestHighLevelClient restHighLevelClient() {RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1", 9200, "http")));return client;}
}

Jsoup爬取京东数据

爬取数据

1、进入京东官网搜索java

在这里插入图片描述

2、按F12审查元素,找到书籍所在位置

在这里插入图片描述
在这里插入图片描述

3、在utils包下建立HtmlParseUtil.java爬取测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hz6j9by4-1610955508957)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210118112732209.png)]

//测试数据
public static void main(String[] args) throws IOException, InterruptedException {//获取请求String url = "https://search.jd.com/Search?keyword=java";// 解析网页 (Jsou返回的Document就是浏览器的Docuement对象)Document document = Jsoup.parse(new URL(url), 30000);//获取id,所有在js里面使用的方法在这里都可以使用Element element = document.getElementById("J_goodsList");//获取所有的li元素Elements elements = element.getElementsByTag("li");//用来计数int c = 0;//获取元素中的内容  ,这里的el就是每一个li标签for (Element el : elements) {c++;//这里有一点要注意,直接attr使用src是爬不出来的,因为京东使用了img懒加载String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");//获取商品的价格,并且只获取第一个text文本内容String price = el.getElementsByClass("p-price").eq(0).text();String title = el.getElementsByClass("p-name").eq(0).text();String shopName = el.getElementsByClass("p-shop").eq(0).text();System.out.println("========================================");System.out.println(img);System.out.println(price);System.out.println(title);System.out.println(shopName);}System.out.println(c);
}

测试结果
在这里插入图片描述
获取结果没问题,下面就把它封装成一个工具类

4、建立一个pojo实体类

实体类Content.java

package com.wu.pojo;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content {private String img;private String price;private String title;private String shopName;//可以自己扩展属性
}

工具类HtmlParseUtil.java

package com.wu.utils;@Component
public class HtmlParseUtil {public List<Content> parseJD(String keyword) throws IOException {List<Content> list = new ArrayList<>();String url = "https://search.jd.com/Search?keyword=" + keyword;Document document = Jsoup.parse(new URL(url), 30000);Element element = document.getElementById("J_goodsList");Elements elements = element.getElementsByTag("li");for (Element el : elements) {String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");String price = el.getElementsByClass("p-price").eq(0).text();String title = el.getElementsByClass("p-name").eq(0).text();String shopName = el.getElementsByClass("p-shopnum").eq(0).text();list.add(new Content(img, price, title, shopName));}return list;}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jpthiq6i-1610955508959)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210118115802010.png)]

5、业务层,这里就不写接口了

ContentService.java

先写一个方法让爬取的数据添加到ES中

package com.wu.service;//业务编写
@Service
public class ContentService {//将客户端注入@Autowired@Qualifier("restHighLevelClient")private RestHighLevelClient client;//1、解析数据放到 es 中public boolean parseContent(String keyword) throws IOException {List<Content> contents = new HtmlParseUtil().parseJD(keyword);//把查询的数据放入 es 中BulkRequest request = new BulkRequest();request.timeout("2m");for (int i = 0; i < contents.size(); i++) {request.add(new IndexRequest("jd_goods").source(JSON.toJSONString(contents.get(i)), XContentType.JSON));}BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);return !bulk.hasFailures();}
}

6、在Controller包下建立

ContentController.java

package com.wu.controller;//请求编写
@RestController
public class ContentController {@Autowiredprivate ContentService contentService;@GetMapping("/parse/{keyword}")public Boolean parse(@PathVariable("keyword") String keyword) throws IOException {return contentService.parseContent(keyword);}
}

7、启动SpringBoot项目,访问它爬取数据添加到ES中

http://127.0.0.1:9090/parse/java

在这里插入图片描述
在这里插入图片描述

实现搜索功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xZLCRWps-1610955508961)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210118131856663.png)]

1、在ContentService.java添加

//2、获取这些数据实现基本的搜索功能
public List<Map<String, Object>> searchPage(String keyword, int pageNo, int pageSize) throws IOException {if (pageNo <= 1) {pageNo = 1;}if (pageSize <= 1) {pageSize = 1;}//条件搜索SearchRequest searchRequest = new SearchRequest("jd_goods");SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//分页sourceBuilder.from(pageNo).size(pageSize);//精准匹配TermQueryBuilder termQuery = QueryBuilders.termQuery("title", keyword);sourceBuilder.query(termQuery);sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));//执行搜索SearchRequest source = searchRequest.source(sourceBuilder);SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);//解析结果List<Map<String, Object>> list = new ArrayList<>();for (SearchHit documentFields : searchResponse.getHits().getHits()) {list.add(documentFields.getSourceAsMap());}return list;
}

2、在ContentController添加搜索请求

@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 {List<Map<String, Object>> list = contentService.searchPage(keyword, pageNo, pageSize);return list;
}

3、访问http://127.0.0.1:9090/search/java/1/10

在这里插入图片描述
欧克,爬取和搜索都没问题,下面要做的就是和前端交互了

和前端交互

1、前端接收数据

index.html

1、用vue接收数据

在这里插入图片描述

<script>new Vue({el: '#app',data: {keyword: '',  //搜索的关键字results: []  //搜索的结果},methods: {searchKey() {var keyword = this.keywordaxios.get('search/' + keyword + '/1/210').then(response => {this.results = response.data;//绑定数据!})}}})
</script>

在这里插入图片描述

2、用vue给前端传递数据
在这里插入图片描述

2、访问 127.0.0.1:9090 并且搜索java

在这里插入图片描述
欧克,完美

实现关键字高亮

1、改ContentService.java里面的搜索功能就行

//3、获取这些数据实现基本的搜索高亮功能
public List<Map<String, Object>> searchPagehighlighter(String keyword, int pageNo, int pageSize) throws IOException {if (pageNo <= 1) {pageNo = 1;}if (pageSize <= 1) {pageSize = 1;}//条件搜索SearchRequest searchRequest = new SearchRequest("jd_goods");SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//分页sourceBuilder.from(pageNo).size(pageSize);//精准匹配TermQueryBuilder termQuery = QueryBuilders.termQuery("title", keyword);//====================================   高   亮   ==========================================HighlightBuilder highlightBuilder = new HighlightBuilder(); //获取高亮构造器highlightBuilder.field("title"); //需要高亮的字段highlightBuilder.requireFieldMatch(false);//不需要多个字段高亮highlightBuilder.preTags("<span style='color:red'>"); //前缀highlightBuilder.postTags("</span>"); //后缀sourceBuilder.highlighter(highlightBuilder); //把高亮构造器放入sourceBuilder中sourceBuilder.query(termQuery);sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));//执行搜索SearchRequest source = searchRequest.source(sourceBuilder);SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);//解析结果List<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();String new_title = "";for (Text text : fragments) {new_title += text;}sourceAsMap.put("title", new_title);  //高亮字段替换掉原来的内容即可}list.add(sourceAsMap);}return list;
}

2、改变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 {List<Map<String, Object>> list = contentService.searchPagehighlighter(keyword, pageNo, pageSize);return list;
}

3、发现问题

需要高亮的字段前缀和后缀都有了,但是这不是我们想要的结果
在这里插入图片描述

4、解决问题

这里Vue给了我们很方便的解决办法
在这里插入图片描述

5、完美

在这里插入图片描述

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

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

相关文章

Gradle的安装与配置

https://www.cnblogs.com/NyanKoSenSei/p/11458953.html Gradle的安装与配置 1. Gradle简介 Gradle是源于Apache Ant和Apache Maven概念的项目自动化构建开源工具&#xff0c;它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置&#xff0c;抛弃了基于XML的各种繁琐配置面…

使用 Roslyn 编译器服务

.NET Core和 .NET 4.6中 的C# 6/7 中的编译器Roslyn 一个重要的特性就是"Compiler as a Service"&#xff0c;简单的讲&#xff0c;就是就是将编译器开放为一种可在代码中调用的服务&#xff0c; 通常在工作流引擎 或是规则引擎中都需要一项功能是计算表达式&#xf…

Rest风格---ElasticSearch

Rest风格 5.1 简介 RESTful是一种架构的规范与约束、原则&#xff0c;符合这种规范的架构就是RESTful架构。 操作 methodurl地址描述PUTlocalhost:9100/索引名称/类型名称/文档id创建文档&#xff08;指定id&#xff09;POSTlocalhost:9100/索引名称/类型名称创建文档&…

IntelliJ IDEA如何导入Gradle项目

https://blog.csdn.net/wangdong5678999/article/details/70255451 IntelliJ IDEA如何导入Gradle项目 栋先生 2017-04-20 10:14:03 95942 收藏 分类专栏&#xff1a; 其他 文章标签&#xff1a; idea intellij idea gradle 版权 最近学习Gradle&#xff0c;本文来重点介绍…

加密货币的本质

转载自 加密货币的本质 去年&#xff0c;比特币暴涨&#xff0c;其他币也像雨后春笋一样冒出来&#xff0c;已经有1000多种了。很多人都在问&#xff0c;加密货币&#xff08;cryptocurrency&#xff09;的时代&#xff0c;真的来临了吗&#xff1f;将来会不会人类不再使用美元…

.net core 源码解析-web app是如何启动并接收处理请求

最近.net core 1.1也发布了&#xff0c;蹒跚学步的小孩又长高了一些&#xff0c;园子里大家也都非常积极的在学习&#xff0c;闲来无事&#xff0c;扒拔源码&#xff0c;涨涨见识。 先来见识一下web站点是如何启动的&#xff0c;如何接受请求,.net core web app最简单的例子,大…

关于文档的基本操作---ElasticSearch

关于文档的基本操作&#xff08;重点&#xff09; 基本操作 添加数据 PUT /psz/user/1 {"name": "psz","age": 22,"desc": "偶像派程序员","tags": ["暖","帅"] }获取数据 GEt psz/user/…

IdentityServer4 使用OpenID Connect添加用户身份验证

使用IdentityServer4 实现OpenID Connect服务端&#xff0c;添加用户身份验证。客户端调用&#xff0c;实现授权。 IdentityServer4 目前已更新至1.0 版&#xff0c;在之前的文章中有所介绍。IdentityServer4 ASP.NET Core的OpenID Connect OAuth 2.0框架学习保护API 。 本文环…

深度优先搜索和广度优先搜索

转载自 深度优先搜索和广度优先搜索 图的应用很广泛&#xff0c;也有很多非常有用的算法&#xff0c;当然也有很多待解决的问题&#xff0c;根据性质&#xff0c;图可以分为无向图和有向图。 图 之所以要研究图&#xff0c;是因为图在生活中应用比较广泛&#xff1a; 图是若…

消息队列 Kafka 的基本知识及 .NET Core 客户端

前言 最新项目中要用到消息队列来做消息的传输&#xff0c;之所以选着 Kafka 是因为要配合其他 java 项目中&#xff0c;所以就对 Kafka 了解了一下&#xff0c;也算是做个笔记吧。 本篇不谈论 Kafka 和其他的一些消息队列的区别&#xff0c;包括性能及其使用方式。 简介 Kafka…

深入解读Service Mesh背后的技术细节

转载自 深入解读Service Mesh背后的技术细节 在Kubernetes称为容器编排的标准之后&#xff0c;Service Mesh开始火了起来&#xff0c;但是很多文章讲概念的多&#xff0c;讲技术细节的少&#xff0c;所以专门写一篇文章&#xff0c;来解析Service Mesh背后的技术细节。 一、…

CentOS7查看和关闭防火墙

https://blog.csdn.net/ytangdigl/article/details/79796961 CentOS7查看和关闭防火墙 蔚蓝色天空sky 2018-04-02 23:22:21 708762 收藏 236 分类专栏&#xff1a; linux 文章标签&#xff1a; centos 防火墙 CentOS 7.0默认使用的是firewall作为防火墙 查看防火墙状态 f…

Visual Studio Code 1.8版本添加了Hot Exit、Zen Mode及更多调试选项

最新发布的Visual Studio Code 1.8版本有许多改进和新功能&#xff0c;包括防止丢失任何编辑信息的Hot Exit&#xff0c;方便开发人员把注意力集中在代码上的Zen Mode&#xff0c;新的调试功能以及更方便的设置等。 Hot Exit是一项新功能&#xff0c;目的是在应用程序崩溃或退出…

ElasticSearch(笔记)

简介 本教程基于ElasticSearch7.6.1, 注意ES7的语法与ES6的API调用差别很大, 教程发布时最新版本为ES7.6.2(20200401更新);ES是用于全文搜索的工具: SQL: 使用like %关键词%来进行模糊搜索在大数据情况下是非常慢的, 即便设置索引提升也有限;ElasticSearch: 搜索引擎(baidu, …

漫画:什么是冒泡排序

转载自 漫画&#xff1a;什么是冒泡排序 什么是冒泡排序&#xff1f; 冒泡排序的英文Bubble Sort&#xff0c;是一种最基础的交换排序。 大家一定都喝过汽水&#xff0c;汽水中常常有许多小小的气泡&#xff0c;哗啦哗啦飘到上面来。这是因为组成小气泡的二氧化碳比水要轻…

CentOS - 修改主机名教程(将 localhost.localdomain 改成其它名字)

https://www.cnblogs.com/gudi/p/7846978.html 需要关闭防火墙&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; Linux修改主机名称 碰到这个问题的时候&#xff0c;是在安装Zookeeper集群的时候&#xff0c;碰到如下问题 java.net.U…

.net core 源码解析-web app是如何启动并接收处理请求(二) kestrel的启动

上篇讲到.net core web app是如何启动并接受请求的&#xff0c;下面接着探索kestrel server是如何完成此任务的。 1.kestrel server的入口KestrelServer.Start (Microsoft.AspNetCore.Hosting.Server.IHttpApplication ) FrameFactory创建的frame实例最终会交给libuv的loop回调…

MySQL中的any_value()函数

https://blog.csdn.net/u014079773/article/details/93722761 https://www.thinbug.com/q/37089347 https://blog.csdn.net/Peacock__/article/details/90608246 https://www.itranslater.com/qa/details/2109775246877262848 4.any_value()会选择被分到同一组的数据里…

MybatisPlus使用

Mybatisplus 导入依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</gro…

.net core 源码解析-mvc route的注册,激活,调用流程(三)

.net core mvc route的注册&#xff0c;激活&#xff0c;调用流程 mvc的入口是route&#xff0c;当前请求的url匹配到合适的route之后&#xff0c;mvc根据route所指定的controller和action激活controller并调用action完成mvc的处理流程。下面我们看看服务器是如何调用route的。…