一个比价系统的构建

在毕设答辩前后,终于可以说说我的毕设内容了。

首先,我做的实际上是一个比价系统,当然,是那种没有用任何 API 的系统。

换言之,我们要做的事情就是从爬虫开始收集数据,处理数据并且通过搜索展示,其中我的论文题目是「数据融合的研究以及应用」,也就是说需要对同样的商品进行聚合(融合)操作。

这篇文章大致提供一个思路,具体的代码因为写的太辣鸡就不开源了。

爬虫

首先就要从爬虫做起了,作为一个爬虫的萌新,要爬电商网站需要遇到的问题:

  • 如何连续不断,或者说可以状态恢复
  • 如何应付反爬
  • 对于客户端渲染的网站如何处理

综合以上考虑(虽然其实考虑的是第三点),决定使用 Selenium 爬取,过去往往配合 Phantomjs,而现在我们可以愉快的使用 Chrome Headless 了。

即使不选择 Selenium 这类库渲染,当然也不是完全没有办法,比如说移动版可能就会做一些服务端渲染;或者直接去分析和请求 API 接口等等,方法可以有很多。

当然作为一个懒人,懒得进行那么多人肉分析和处理,所以直接用 Selenium 开撸。

对于每个电商网站都有分类的部分,可以从分类开始一页一页爬,也就是说如果要爬全站的话,实际上深度为 3 级就能搞定了。对于这三个步骤而言是统一的,各步骤可以单独写一个程序,各个步骤之间通过中间件或者数据库联系可以做到完全独立,互不干扰,也有助于直接部署到多台机器上。

对于一般的 Python 爬虫分布式,似乎通常都是用 Redis 去做的。

这样其实也就给了每一条数据一个状态,提出的问题 1 也就解决了。

问题 2 是个比较麻烦的问题,主流的做法依旧是:

  1. 减速
  2. 代理 IP 池
  3. 模拟操作

不过,这里不得不吐槽,除了一点 Cookie 上的验证之外,由于 Selenium + Driver 的组合实在略慢,加上我需要的实验数据量比较小,根本没有遇到需要反爬的问题……

融合

融合在这里根据引言部分其实被转换为了一个实体识别的问题,我们在这里假定:「品牌」、「型号」与「颜色」信息一致的为同一商品,考虑到复杂性,实际上我们只需要一个 Title 信息,对 Title 进行处理,对于其他数据则作为展示用可以选择性采集。

「品牌」我们可以直接通过品类的列表获取,进行一些处理和合并操作就可以得到一个完整的「品牌」别名列表,当然,还有一些其他的做法,比如说寻找同义词典,在一个特殊的应用环境下没必要这么做。

对 Title 进行的第一个处理就是去除商品 Title 中的所有品牌信息,贪婪匹配删除一波之后留下的就是包括了「颜色」、「型号」等信息。

先从颜色入手,我们建立了一张「颜色色系表」,不需要特别全,最后一个关键词为「色」,应该可以匹配一些流氓颜色名了。

分词操作,可以使用结巴分词,然后匹配到颜色同样在字符串中剔除这一部分。

最后找到型号,我们可以假定型号在品牌之后,剔除后也就是首个,结束。

于是我们得到了一个特征序列,根据这一特征序列就可以确定是否为同一实体。当然,之后我想到,这其实和机器学习的思路是一致的,但这个问题肯定是一个监督学习问题,实在懒得标注训练集和测试集,所以……如果把特征值处理为特征向量可以进行一些其他的操作,或者说 Title 本身就可以通过训练做一些操作,不过那是后话。

搜索与界面

搜索当然是选择 ElasticSearch 拉。

我们把融合处理后的结果丢进了 MongoDB,之后使用 mongo-connector 同步,关于这个还写了一个文章吐槽:使用 mongo-connector 同步 MongoDB 数据库到 ElasticSearch

同步完成之后,搜索到的打分最高的项特征值去匹配数据库,就能得到我们的「融合结果」了。

结束

很惭愧,一点微小的吐槽,其实并没有什么卵用。

如果您觉得文章不错,可以通过赞助支持我

标签: 知识

已有 9 条评论

  1. 博主,因为本人的毕设也是和你的类似,我实现是用了java的爬虫和安卓的客户端,因为在数据存储到mysql中后不知道如何去进行数据融合,导致指导老师卡我(哭泣脸),特来请教数据融合的经验

    1. 最简单的方法可以用字符串匹配,首先我不知道你要构建的是怎么样的一个系统,可以从实体识别的角度去切入,这是最简单的,准确度也实在不怎么样,提升空间也很小,但是本科生毕业绰绰有余

      1. 毕设题目是基于安卓的商品比价,在很久之前我都只保存历史搜索结果,突然一下要我基于历史检索做一个,商品价格历史记录,遇到的问题就是每次搜索的关键词类似然后结果也类似,最后实在不知道怎么去处理我完全的保存获取的商品信息,基于这个数据表去建立新的表然后基于新的表做历史记录查询,卡在整合我之前杂乱无张的数据中,谷歌搜索第一个就是博主这篇博文,所以才会有如此回复

        1. 根据不同商品,我在抓取数据源时已经默认保存了 url 和条目的 createdAt,只要你的爬虫是可以持久化的,历史记录这一点不成问题,由这两个特征(当然我还加了 type 信息表示所在的站点,因为是根据站点写的规则所以站点名是可枚举的)可以整理出各个站点某商品的价格变化,根据文章中仅仅通过时间聚合可以得到一定时间内最低价格的变化等等,这些都取决于聚合的数据库语句怎么写,或者交由 ElasticSearch 处理,没有多大问题。

  2. hanson

    有一个问题,对于爬虫将数据持久化,如果如果 遇到价格变更或者别的属性变更怎么办呢。还是根本就没有考虑过实时的数据捕捉。

    1. updateOrInsert (逃

    2. 不过这里确实处理的比较粗糙 如果 Title 描述有修改就很尴尬了

  3. 禁锢

    过来学学数据融合思路

  4. xiaoD

    大三就毕设了?这是多牛

添加新评论