爬虫项目-数据存储

ElasticSearch简介

  • 全文搜索引擎
  • 存储:无需建表,使用json格式的文档
  • 搜索:按关键词搜索,无需拼装查询语句

ElasticSearch入门

REST简介

  • HTTP方法 + 地址
  • 方法是动词,地址是名词
  • 方法包括GET/PUT/POST/DELETE/PACTH/HEAD等

host:9200/index/type/id

这是访问ElasticSearch的层次结构,对比关系型数据库

  • index相当于database
  • type相当于table
  • 不需要预先创建index和type
  • type中数据类型可以不一致

用法注意

  • 获取数据使用Get方法
  • 添加数据若使用Put方法,必须带id,并在Request Body中携带要添加的内容
  • 添加数据若使用Post方法,可省略id,并在Request Body中携带要添加的内容
  • 查询内容使用Get或Post方法,并且Request Body为空
  • 全局查询/_search,特定查询在Request Parameters中添加条件

数据存储

使用elasticsearch go client通过代码将爬取到的有价值的信息存储到其中

重新设计数据结构

  • 原Profile结构体保存的是用户个人信息,而对于爬虫应用来讲,访问链接信息编号是必须具备的
  • 从elasticsearch的index/type/id三元组的格式出发,不同type相当于不同的table,id最好与type有关联,比如珍爱网的数据编号最好与珍爱网这张表有关
  • 设计新的数据格式如下
type Item struct {
    Url string
    Type string
    Id string

    Payload interface{}
}

数据去重

1.爬取的时候进行url去重
由于珍爱网会展示重复的用户,所以使用一个map来存储已经访问过的用户页面的地址,每次提交爬取任务前,在map中检查该任务对应的url是否已经访问过,若是,就无需提交该任务。

for _, r := range result.Requests {
  //检查待爬取的任务的url是否已经执行,若是,则跳过该次循环
    if isDuplicate(r.Url) {
      continue
    }
    ce.Scheduler.Submit(r)
}

2.存储的时候根据id去重
第一条url去重可以解决单次运行情况下的重复问题,但程序停止再运行时,仍然会从零开始获取数据,而这些数据已经在elasticsearch中存在了;
因此由elasticsearch可以根据id存储数据的特点,为每条数据设计唯一的id,避免程序多次运行时的重复存储问题;
设计id比较复杂,而从现有的用户页面的地址中取出id是非常方便的,珍爱网已经为每个用户的详情页分配了一个id:album.zhenai.com/u/1159751830

代码优化

1、只建立一个client连接到elasticsearch,而不是每做一次存储动作都得重新创建客户端:

func ItemSaver() (chan engine.Item, error) {
//先创建一个客户端,之后传递到真正干活的save()函数
    client, err := elastic.NewClient(elastic.SetURL("http://3.226.45.27:9200"), elastic.SetSniff(false))
    if err != nil {
        return nil, err
    }
    out := make(chan engine.Item)
    go func() {
        ......
        for {
          err := save(client, item)
        }
       .......
    }()
    return out, nil
}

2、函数式编程的改造(没怎么懂,详见视频16-8)

func profileParser(name, gender, url string) engine.ParserFunc {
    return func(bytes []byte) engine.ParseResult {
        return ParseProfile(bytes, name, gender, url)
    }
}

3、index名称改为外部配置

之前index的名称是在save()函数的内部写死了的,elasticsearch中的index相当于关系型数据库中的database,应该由外部配置。因此,save()函数需要一个index名称参数,即ItemSaver()函数需要一个index名称参数,这样就可以在启动的时候配置index:

itemChan, err := persist.ItemSaver("dating_profile")

func save(client *elastic.Client, index string, item engine.Item) error {}
全部评论

相关推荐

刚刷到字节跳动官方发的消息,确实被这波阵仗吓了一跳。在大家还在纠结今年行情是不是又“寒冬”的时候,字节直接甩出了史上规模最大的转正实习计划——ByteIntern。咱们直接看几个最硬的数,别被花里胡哨的宣传词绕晕了。首先是“量大”。全球招7000多人是什么概念?这几乎是把很多中型互联网公司的总人数都给招进来了。最关键的是,这次的资源分配非常精准:研发岗给了4800多个Offer,占比直接超过六成。说白了,字节今年还是要死磕技术,尤其是产品和AI领域,这对于咱们写代码的同学来说,绝对是今年最厚的一块肥肉。其次是大家最关心的“转正率”。官方直接白纸黑字写了:整体转正率超过50%。这意味着只要你进去了,不划水、正常干,每两个人里就有一个能直接拿校招Offer。对于2027届(2026年9月到2027年8月毕业)的同学来说,这不仅是实习,这简直就是通往大厂的快捷通道。不过,我也得泼盆冷水。坑位多,不代表门槛低。字节的实习面试出了名的爱考算法和工程实操,尤其是今年重点倾斜AI方向,如果你简历里有和AI相关的项目,优势还是有的。而且,转正率50%也意味着剩下那50%的人是陪跑的,进去之后的考核压力肯定不小。一句话总结: 27届的兄弟们,别犹豫了。今年字节这是铁了心要抢提前批的人才,现在投递就是占坑。与其等到明年秋招去千军万马挤独木桥,不如现在进去先占个工位,把转正名额攥在手里。
喵_coding:别逗了 50%转正率 仔细想想 就是转正与不转正
字节7000实习来了,你...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务