我的Go+语言初体验——用Go+写个爬虫并进行数据处理

小生凡一 社区中级贡献者
Golang领域优质创作者
2021-11-30 09:59:58

“我的Go+语言初体验” | 征文活动进行中……

 

写在前面

是这样的!我个人是Go语言爱好者,接触七牛是在大一的时候,这几天七牛云带着Go+来CSDN征文!那我就用Go+写一个爬虫吧!

项目初始化

前面我们已经完成了go+的搭建,然后我们建立一个项目吧!用vscode吧,因为goland没有goplus的插件。

  • 创建一个.gop文件

在这里插入图片描述

 

  • 写入hello world 测试能否跑通

在这里插入图片描述

 

gop run main.gop

但是会出错

在这里插入图片描述

 


这里提示gop.mod没有找到!

 

此时我们应该要先gop mod一下包名! 注意!! 我们一定要用gop mod

虽然用go mod可以执行,但是不是gop的mod而是go的mod,我一开始就是用go mod进行init的,但是许老师说是要gop mod的!!

在这里插入图片描述

 

然后就会出现这个东西gop mod文件了

然后我们继续跑一下!

在这里插入图片描述

 


就会有这个错,此时我们只需要按照他的要求,go get一下这个builtin就可以了
在这里插入图片描述

 


之后就可以跑出来了
在这里插入图片描述

 

那我们用Go+写一个爬虫吧!

1. 找到blink

CSDN呢,要切换成新版才能看到blink的!我本来是旧版的,就先切换一下新版。
我们就找到了

在这里插入图片描述

 

2. 分析页面

我们发现并没有相应的接口显示评论,所以我们点击更多之后

在这里插入图片描述

 


就会出现这个了,这个就是我们的爬取地址了!
在这里插入图片描述

 


然后我们看一下这个url,返回就是我们所需要的评论信息!
在这里插入图片描述

 


然后我们看响应参数!
在这里插入图片描述

 

  • pageNum就是页码
  • pageSize就是页面大小
  • blinkId就是这个blink的id了

那么我们可以直接让pageNum=1pageSize=500,直接返回全部的评论!
舒服了!

3. 编写代码

如果你不喜欢在goland中没有go-plus插件的提示的话,可以在vscode上创建,这样可以有高亮的提示了。

在这里插入图片描述

 

3.1 发送请求

使用net/http包,构造一个client

client := &http.Client{}
reqSpider, err := http.NewRequest("GET", "https://blink-open-api.csdn.net/v1/pc/blink/allComment?pageNum=1&pageSize=400&blinkId=1260435", nil)
if err != nil {
    println (err)
}
reqSpider.Header.Set("content-length", "0")
reqSpider.Header.Set("accept", "*/*")
reqSpider.Header.Set("x-requested-with", "XMLHttpRequest")
respSpider, err := client.Do(reqSpider)
if err != nil {
    println (err)
}
bodyText, _ := ioutil.ReadAll(respSpider.Body)

3.2 解析数据

我们通过刚刚查看响应的方式情况,可以看到这是标准的json格式的数据,

所以我们可以使用json包,将string转化成结构体的json格式

    var result BlinkResult
    _ = json.Unmarshal(bodyText, &result)

3.3 数据处理与分析

  • 查看24天前的这一天的所有留言记录
    count := 0
    // 如果存在20天前发表的内容,打印出内容
    if ({for item <- items, item.CreateTime == "24 天前"}) { // 注意这里一定要有括号, 返回bool
        for item <- items, item.CreateTime == "24 天前" {
            count++
            println item
        }
        printf("一共有%d人在24天前留言", count)
    }

在这里插入图片描述

 

  • 查看所有评论的来源平台
    for item <- items {
        switch item.FromType {
        case "CSDN-APP:Android:":
            countAndroid++
            userAndroid = append(userAndroid, item)
        case "CSDN-APP:iOS:":
            countIOS++
            userIOS = append(userIOS, item)
        case "pc":
            countPC++
            userPC = append(userPC, item)
        default:
            countOrder++
        }
    }

在这里插入图片描述

 

  • 做一个小升级,我们统计各个平台的平均评论时间
    countAndroid, countIOS, countPC, countOrder, all := 0, 0, 0, 0, len(items)
    meanDayIOS, meanDayAndroid, meanDayPC := 0, 0, 0
    tmp := 0
    var userAndroid []LuckyBlinkPerson
    var userIOS []LuckyBlinkPerson
    var userPC []LuckyBlinkPerson
    // 统计所有的来源平台以及平均评论天数
    for item <- items {
        switch item.FromType {
        case "CSDN-APP:Android:":
            countAndroid++
            tmp, _ = strconv.Atoi(item.CreateTime[:2])
            userAndroid = append(userAndroid, item)
            meanDayAndroid += tmp
        case "CSDN-APP:iOS:":
            countIOS++
            userIOS = append(userIOS, item)
            tmp, _ = strconv.Atoi(item.CreateTime[:2])
            meanDayIOS += tmp
        case "pc":
            countPC++
            userPC = append(userPC, item)
            tmp, _ = strconv.Atoi(item.CreateTime[:2])
            meanDayPC += tmp
        default:
            countOrder++
        }
    }
    printf("来自Android有:%d人 平均评论天:%d天前\n", countAndroid, meanDayAndroid/len(userAndroid))
    printf("来自iOS有:%d人 平均评论天:%d天前\n", countIOS, meanDayIOS/len(userIOS))
    printf("来自pc有:%d人 平均评论天:%d天前\n", countPC, meanDayPC/len(userPC))
    printf("其他的有:%d人\n", countOrder)
    printf("一共有%d人\n", all)

在这里插入图片描述

 

  • 然后我们统计出哪天评论了多少人
    // 统计评论天数每一天有多少人评论
    mapDay := map[string]int{}
    meanDayIOS, meanDayAndroid, meanDayPC = 0, 0, 0
    for user <- items {
        mapDay[user.CreateTime]++
    }
    for k, v <- mapDay {
        printf("%s 评论了 %d 条信息\n", k, v)
    }

在这里插入图片描述

 

  • 返回所有在20天前的这一天评论的安卓用户的昵称,内容,创建时间
    androidCommont := [[user.NickName, user.Content, user.CreateTime] for user <- userAndroid, user.CreateTime == "20 天前"]
    if len(androidCommont) != 0 {
        for androidInfo <- androidCommont {
            println androidInfo
        }
    }

在这里插入图片描述

 

  • 去除重复的用户名称的评论数据
func removeBlinkRepByMap(slc []LuckyBlinkPerson) []LuckyBlinkPerson {
    var result []LuckyBlinkPerson
    tempMap := map[LuckyBlinkPerson]byte{}
    for _, e <- slc {
        l := len(tempMap)
        tempMap[e] = 0
        if len(tempMap) != l {
            result = append(result, e)
        }
    }
    return result
}

3.4 输出所有的评论

    var luckyBPList []LuckyBlinkPerson
    for _, v <- commentList {
        var luckBlinkPerson LuckyBlinkPerson
        luckBlinkPerson.UserName = v.Username
        luckBlinkPerson.NickName = v.Nickname
        luckBlinkPerson.CreateTime = v.CreateTime
        luckBlinkPerson.Content = v.Content
        luckyBPList = append(luckyBPList, luckBlinkPerson)
    }
    luckyBPList = removeBlinkRepByMap(luckyBPList)
    for _, v <- luckyBPList {
        println v.NickName, v.Content, v.CreateTime
    }

完整代码在github上:

https://github.com/CocaineCong/go-plus-demo

总结

怎么说呢,写完爬虫感觉,这个好像有点写python的感觉,毕竟我是数据科学专业的,经常用到python进行数据处理….

Go+的领域就是面向数据分析的,Go+的爬虫很快!性能也比python牛,语法也相似

相信Go+的未来一定会如同其创始公司一样,7777777牛起来!

也希望我能为Go+社区尽一份绵薄之力,一份Go+爬虫送给大家!

...全文
279 2 打赏 收藏 举报
写回复
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
海拥✘ 2021-12-01
  • 打赏
  • 举报
回复

牛牛牛

小生凡一 社区中级贡献者 2021-11-30
  • 打赏
  • 举报
回复 1
发帖
Go+ 开发者社区

906

社区成员

Go+ 官方开发者社区。我们希望向广大的开发者和数据科学家介绍 Go+ 的定位和意义,并邀请更多开发者一起贡献代码、共建 Go+ 生态。 Go+ 官网:https://goplus.org/
其他 企业社区
社区管理员
  • Go+
  • 杨东杰
加入社区
帖子事件
创建了帖子
2021-11-30 09:59
社区公告

本社区为 Go+ 官方开发者社区。我们希望向广大的开发者和数据科学家介绍 Go+ 的定位和意义,并邀请更多开发者一起贡献代码、共建 Go+ 生态。

Go+ 官网:https://goplus.org/
GitHub地址:https://github.com/goplus/gop