• es-jd


    es-jd

    依赖

    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.8.0</elasticsearch.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <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>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.13.1</version>
        </dependency>
    </dependencies>
    

    实体类

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Goods {
        private String name;
        private String price;
        private String img;
    }
    

    工具类方法

    public List<Goods> getGoods(String keyword) throws IOException {
        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");
        List<Goods> List = new ArrayList<>();
        for (Element li : elements) {
            Elements el = li.getElementsByTag("img").eq(0);
            String img = el.attr("src").equals("") ? el.attr("source-data-lazy-img") : el.attr("src");
            String price = li.getElementsByClass("p-price").eq(0).text();
            String name = li.getElementsByClass("p-name").eq(0).text();
            Goods goods = new Goods(name, price, img);
            List.add(goods);
        }
        return List;
    }
    

    配置config

    @Configuration
    public class ElasticSearchClientConfig {
        @Bean
        public RestHighLevelClient restHighLevelClient() {
            RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(
                            new HttpHost("localhost", 9200, "http")));
            return client;
        }
    }
    

    service层

    @Service
    public class GoodsService {
    
        @Autowired
        private HttpParseUtil httpParseUtil;
    
        @Autowired
        private RestHighLevelClient restHighLevelClient;
    
        public boolean parseJD(String keyword) throws IOException {
            List<Goods> list = httpParseUtil.parseJD(keyword);
            BulkRequest request = new BulkRequest();
            request.timeout("2m");
    
            for (int i = 0; i < list.size(); i++) {
                request.add(
                        new IndexRequest("jd_goods")
                                .source(JSON.toJSONString(list.get(i)), XContentType.JSON)
                );
            }
            BulkResponse response = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
            return !response.hasFailures();
        }
    
    
        public List<Map<String, Object>> searchJD(String keyword, int pageNo, int pageSize) throws IOException {
            if (pageNo <= 1) {
                pageNo = 1;
            }
            SearchRequest request = new SearchRequest("jd_goods");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            //分页
            sourceBuilder.from(pageNo);
            sourceBuilder.size(pageSize);
            //精准匹配
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", keyword);
            sourceBuilder.query(termQueryBuilder);
            sourceBuilder.timeout(TimeValue.timeValueSeconds(60));
    
            request.source(sourceBuilder);
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
    
            List<Map<String, Object>> list = new ArrayList<>();
    
            for (SearchHit documentFields : response.getHits().getHits()) {
                list.add(documentFields.getSourceAsMap());
            }
            return list;
        }
    
        //高亮搜索
        public List<Map<String, Object>> searchJDHighLight(String keyword, int pageNo, int pageSize) throws IOException {
            if (pageNo <= 1) {
                pageNo = 1;
            }
            SearchRequest request = new SearchRequest("jd_goods");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            //分页
            sourceBuilder.from(pageNo);
            sourceBuilder.size(pageSize);
            //精准匹配
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", keyword);
            sourceBuilder.query(termQueryBuilder);
            sourceBuilder.timeout(TimeValue.timeValueSeconds(60));
    
            //高亮
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.field("name");
            highlightBuilder.preTags("<span style='color:red'>");
            highlightBuilder.postTags("</span>");
            sourceBuilder.highlighter(highlightBuilder);
    
            request.source(sourceBuilder);
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
    
            List<Map<String, Object>> list = new ArrayList<>();
    
            for (SearchHit hit : response.getHits().getHits()) {
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField name = highlightFields.get("name");
                System.out.println("name->" + name);
                Map<String, Object> map = hit.getSourceAsMap();
                if (name != null) {
                    Text[] fragments = name.fragments();
                    String _name = "";
                    for (Text fragment : fragments) {
                        _name += fragment;
                    }
                    map.put("name", _name);
                }
                list.add(map);
            }
            return list;
        }
    }
    

    controller层

    @RestController
    public class GoodsController {
    
        @Autowired
        GoodsService goodsService;
    
        @GetMapping("/parse/{keyword}")
        public boolean parseJD(@PathVariable("keyword") String keyword) throws IOException {
            return goodsService.parseJD(keyword);
        }
    
        @GetMapping("/search/{keyword}/{pageNo}/{pageSize}")
        public List<Map<String, Object>> searchJD(@PathVariable("keyword") String keyword,@PathVariable("pageNo")  int pageNo,@PathVariable("pageSize")  int pageSize) throws IOException {
            return goodsService.searchJDHighLight(keyword, pageNo, pageSize);
        }
    }
    

    前端页面

    ...
    
    <form name="searchTop" class="mallSearch-form clearfix">
        <fieldset>
            <legend>京东搜索</legend>
            <div class="mallSearch-input clearfix">
                <div class="s-combobox" id="s-combobox-685">
                    <div class="s-combobox-input-wrap">
                        <input v-model="keyword" type="text" autocomplete="off" value="dd"
                               id="mq"
                               class="s-combobox-input" aria-haspopup="true">
                    </div>
                </div>
                <button type="submit" @click.prevent="search" id="searchbtn">搜索</button>
            </div>
        </fieldset>
    </form>
    
    ,,,
    
    <!-- 商品详情 -->
    <div class="view grid-nosku">
        <div class="product" v-for="result in results">
            <div class="product-iWrap">
                <!--商品封面-->
                <div class="productImg-wrap">
                    <a class="productImg">
                        <img :src="result.img">
                    </a>
                </div>
                <!--价格-->
                <p class="productPrice">
                    <em><b>¥</b>{{result.price}}</em>
                </p>
                <!--标题-->
                <p class="productTitle">
                        <a> {{result.name}} </a>-->
                    <a  v-html="result.name"></a>
                </p>
                <!-- 店铺名 -->
                <div class="productShop">
                    <span>店铺名</span>
                </div>
                <!-- 成交信息 -->
                <p class="productStatus">
                    <span>月成交<em>999笔</em></span>
                    <span>评价 <a>3</a></span>
                </p>
            </div>
        </div>
    </div>
    
    ...
    
    <script>
        new Vue({
            el: '#app',
            data: {
                keyword: '',
                results: []
            },
            methods: {
                search() {
                    var keyword = this.keyword
                    axios.get('/search/' + keyword + '/1' + '/20').then(res=>{
                        this.results = res.data;
                    })
                }
            }
        })
    </script>
    
  • 相关阅读:
    Python-Collections模块之defaultdict
    Python-Collections模块之deque
    Python-Collections模块之NameTuple
    Python-Collections模块之OrderedDict
    @常见的远程服务器连接工具:Xshell与secureCRT的比较!!!(对于刚接触的测试小白很有帮助哦)
    告诉你:传统测试和敏捷测试的区别!!!(比较全的解答,一看便明白)
    @软件测试环境搭建的详细流程(初学者不要错过哦,很实用)!!!!
    Netlib文件转化为mps文件
    新设备关联Gitlab
    CMake与OpenMP
  • 原文地址:https://www.cnblogs.com/pinked/p/13633157.html
Copyright © 2020-2023  润新知