# 商品比价系统 **Repository Path**: chenweibiao2019/price-parity-of-commodities ## Basic Information - **Project Name**: 商品比价系统 - **Description**: 商品比价系统(基于网络爬虫) - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 57 - **Forks**: 23 - **Created**: 2019-12-17 - **Last Updated**: 2026-02-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 商品比价系统 #### 介绍 商品比价系统(基于网络爬虫) - 模块介绍: ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/095524_80623157_5169770.png "屏幕截图.png") 1. crawler:采用的是selenium框架(java实现),用它来爬虫,并将爬取的商品数据入库。 2. display:是网页展示模块,你可以在该模块搜索需要比价的商品。查看商品的价格变化曲线,商品评分等。 3. search:查询模块,采用lucene全文检索框架,建立倒排索引以及分词搜索 4. evaluate:商品信息分析,对库中的数据进行分析打分,将更优秀的商品展示给用户。(基于商品销量、商品评论量、商品收藏量、粉丝数等条件打分) 5. management:项目模块管理,心跳机制,可以监控当前各模块的健康状况。 #### 软件架构 由springboot开发、各模块之间通过Dubbo进行方法调用、Zookeeper作为服务注册中心、消息队列采用了activeMq(目前生产都不用了,原因是开发社区、性能因素),版本控制采用Maven、Mysql8.0 #### 后续改进方向 1. crawler:目前采用的是java爬虫,如果需要更专业的爬虫,你可以采用 **python实现** 。另外需要考虑的是电商网站的反爬技术,否则会出现如下场景: ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/095040_58c7b749_5169770.png "屏幕截图.png") 还有如果你需要登录一个天猫淘宝账号进行爬虫,那么一段时间后,你的登录token也会过期,此时就会出现如下页面: ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/103414_3583cb13_5169770.png "屏幕截图.png") 2. crawler:由于后续业务发展,爬虫获取到的数据量会非常大,单机Mysql已无法承载,你需要考虑进行 **分库分表** 3. search: lucene是一个比较老的全文检索框架,它没有集群方案。面对大数据量、准实时的商品信息搜索,你需要使用当前比较流行的 **ElasticSearch** 去优化它。我在代码里已经留了接口,你可以增加一个实现。 4. evaluate:当前的商品评价模型相对比较简易,如果需要更加可靠的商品评价方案,你需要去改进它。 #### 效果展示 1.用户进入商品比价网站,在页面上方搜索框输入想要搜索的商品关键词,点击搜索,就可以搜索到相关商品的信息。在搜索结果中,可以查看搜索到相关商品的数量、商品的图片、商品描述、商品价格、评论数量、所在商城、商品评分和推荐理由等信息。同时用户可以对搜索结果进行价格、销量进行排序,根据商品的价格区间进行筛选,来满足用户的个性化需求。在搜索结果上方可以看到商城报价的筛选条件,选中相应的商城,可以看到本商城的商品信息,在此基础上,商品显示采用分页显示,提高网页的加载速度和渲染效果,提高用户的购物效率。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/104303_c5056ac8_5169770.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/104158_368157a3_5169770.png "屏幕截图.png") 2.数据爬取模块是将爬取到的商品过滤后保存在数据库中,提供系统的数据支撑。数据主要包含商品编号、商品名称、商品历史价格、商品分类ID、商品分类名称、销量、评论量、收藏量、库存量、发货地址、店铺ID、店铺名称、商品图片、店铺描述评分、店铺服务评分、店铺物流评分、商品规格信息、商品URL、商品详情、商品系统评分、推荐理由、爬取时间、当前价格等字段,爬取工具采用selenium驱动浏览器(FireFox)进行商品信息爬取。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/104414_de7b6453_5169770.png "屏幕截图.png") ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/104419_9e1a8022_5169770.png "屏幕截图.png") 3.商品搜索模块会将数据库中的商品信息进行分词索引,保存在内存或磁盘中,供Lucene全文检索使用,以此来提高搜索的效率。通过Lucene索引查看工具Luke对索引信息进行查看,在该图的左上角可以看到索引存储的位置、索引的域空间数量(Number of fields)、被索引的文档数目(Number of documents)等信息,在该图下方,可以查看不同的域索引所占的不同比率,代表每个域中的数据量不同,从图中可知,商品名称(productName)所占的数据量最大,为30.64%,可见商品数据中商品名称占了较大的一部分。选中其中一个域,可以看到当前域中索引的详细信息,包含索引内容(Text),如此处的“新款”,“音响”等,以及相应索引出现的频率(Freq)。这些都是Lucene全文检索时必须的数据基础。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/104514_d3d93373_5169770.png "屏幕截图.png") 4.商品评价模块负责对商品信息进行评价,评价结果包含商品评分以及推荐理由。商品评分采用商品的模糊评价模型,推荐理由主要包含一些可量化的维度,如销量、商品描述、商品评价等。不同的商品评分将会影响到商品搜索的结果,评分较高的商品将优先展示给用户。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/104553_ee2676d4_5169770.png "屏幕截图.png") 5.后台管理模块包含模块监控、评价模型配置、商品信息维护功能。 在模块监控中,各模块采用Sigar工具包获取到当前服务器的网络延迟、带宽占用、内存占用、CPU占用等信息并返回给后台管理系统,系统管理员可以看到当前正在运行的所有模块信息,做到系统的及时预警与防护,提高系统的安全性。同时后台管理员可以对模块信息进行管理,对有问题的模块信息进行新增、修改或删除。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/104610_1d6743fb_5169770.png "屏幕截图.png") 评价模型配置功能可以对评价模型的权重指标进行配置,来修改模型各指标的权重系数,提供模型的灵活性,降低维护成本,能及时适应不同的评价指标。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/104623_99fd4ccb_5169770.png "屏幕截图.png") 商品信息维护页面可以对不符合条件的商品数据进行维护,从数据库中通过JAVA的javax.validation包筛选出不符合条件的商品数据,并给出不符合的理由,后台管理员可以对不符合条件的数据一目了然,点击上方“更新数据”按钮对数据库数据进行更新,同时可以对商品信息进行修改与删除操作。 ![输入图片说明](https://images.gitee.com/uploads/images/2021/0222/104629_31cb0a3c_5169770.png "屏幕截图.png") #### 如何启动它 0、启动顺序:crawler -> search -> display 其余无顺序 依赖关系:crawler是基础模块,search依赖于crawler 爬取的数据,display依赖于search的索引。 1. crawler:如果采用selenium进行爬虫,你需要安装浏览器与对应的浏览器驱动。我用的是firefox:82.0.3 (64 位),对应的浏览器驱动上传了一份在 price-parity-of-commodities/ geckodriver.exe 根目录下,你可以修改crawler/src/main/resources/application.properties中的配置来修改 ```java diff.broswer.path=D:\\ruanjian\\firefox\\firefox.exe diff.broswer.driver.path=D:\\webDriver\\geckodriver-v0.23.0-win32\\geckodriver.exe ``` ##### 关于爬虫思路: 我当时的想法很简单,就是爬数据。使用的方法也不是真正爬虫的思路,不断的探寻外链,深入爬取。而是先爬取商品种类名称,然后去天猫淘宝输入关键字,查询商品,然后一个商品一个商品爬取。于是乎: 通过调用接口CategoryController#crawlerCategory爬取商品种类,地址为https://m.tmall.com/mblist/category/index.html,但很不幸,这个网站好像没用了。 然后通过接口ProductController#startCrawler爬天猫,通过ProductController#startCrawlerJD爬京东。当你调用了响应的接口后,就会启动相应的浏览器进行爬取。 爬虫的url分别为天猫、京东的首页Url即可。 2、数据库表设计,你可以参考crawler/src/main/resources/application.properties中的数据库连接来配置该数据库(因为脚本找不到了,只留下文档): ``` spring.datasource.url = jdbc:mysql://localhost:3306/products?serverTimezone=UTC&useSSL=false ``` 数据库名称:products 商品信息表(product)25个字段 |伦理名 | 物理名 |属性| 主键| 外键| 说明| |---|---|---|---|---|---| |编号| id| Int(16)| Y | |商品编号| product_id varchar(32) | |商品名称| product_name varchar(256)| |商品价格(历史价格 ‘,’隔开)| price| text| |商品分类ID| category_id| varchar(32) | |商品分类名称| category_name |varchar(32)| |销量| sellCount |varchar(32)| |评论量| reviewCount| varchar(32) | |收藏量| collectCount| varchar(32) | |库存量| stock| Int(8)| |发货地址| delivery_Add| Varchar(32)| |店铺ID| shop_id varchar(32)| |店铺名称| shop_name| varchar(256)| |商品图片| product_img |text | |店铺描述评分| shopdsr_ms| Double(2) | |店铺服务评分| shopdsr_fw| Double(2) | |店铺物流评分| shopdsr_wl| Double(2)| |商品sku信息| product_sku| text | |商品URL| Product_Url| varchar(1024) | |商品详情 |product_detail |text | |商品系统评分 |product_score| Double(4) | |推荐理由| recommended_reason| varchar(1024) | |爬取时间| update_time |text | |备用字段1(当前价格)| spare_field1 |double | |备用字段2| spare_field2 |text | |备用字段3| spare_field3| text | 商品种类信息表(category) |伦理名| 物理名| 属性| 主键| 外键| 说明| |---|---|---|---|---|---| |编号| id| Int(16)| Y | |商品种类ID| category_id| varchar(32)| |商品种类名称1| category1_name |VARCHAR(64) | |商品种类名称2| category2_name| VARCHAR(64) | |商品种类名称3| category3_name| VARCHAR(64) | 代理ip信息表(proxyIp) |伦理名| 物理名| 属性| 主键 |外键| 说明| |---|---|---|---|---|---| |编号| id| Int(16)| Y | |Ip地址| ip_address| varchar(32) | |Ip端口号| ip_port| VARCHAR(8)| |服务器地址| server_address| VARCHAR(64) | |验证时间| check_time| VARCHAR(64)| |更新时间| update_time| date | 模糊评价模型一级指标表Indicators1 |伦理名 |物理名 |属性 |主键 |外键| 说明| |---|---|---|---|---|---| |编号| id| Int(16) |Y | |类目名称 |indicators_1_name| varchar(64) | |类目权重 |indicators_1_weight |Double(4,2) | |备用字段1| spare_field1| Varchar(128) | 模糊评价模型二级指标表Indicators2 |伦理名| 物理名| 属性| 主键| 外键| 说明| |---|---|---|---|---|---| |编号| id| Int(16)| Y| |类目名称 |indicators_2_name| varchar(64) | |类目权重| indicators_2_weight| Double(4,2) | |对应一级类目id |indicators_1_id| Int(8) | |备用字段1 |spare_field1 |Varchar(128) | 模糊评价模型三级指标表Indicators3 |伦理名| 物理名 |属性| 主键| 外键| 说明| |---|---|---|---|---|---| |编号 |id| Int(16)| Y | |类目名称| indicators_3_name| varchar(64) | |类目权重| indicators_3_weight| Double(4,2) | |对应二级类目id| indicators_2_id |Int(8)| |备用字段1| spare_field1| Varchar(128) | 模块节点信息表(module-info) |伦理名 |物理名| 属性| 主键| 外键| 说明| |---|---|---|---|---|---| |编号| id| Int(16)| |Y | |模块名称| module_name |varchar(64) | |模块所在ip| module_ip| Varchar(64)| |模块所在端口号| module_port| Varchar(8)| |延迟(ms)| module_latency| Int(8) | |带宽占用率| occupiedRate_of _Bandwidth | Double(4,2) | |内存占用率| occupiedRate_of_memory |Double(4,2)| |Cpu占用率| occupiedRate_of_cpu| Double(4,2)| |模块运行状况 |module_condition| boolean | 模块运行正常与否| #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request