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

Posted 小生凡一

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的Go+语言初体验——用Go+写个爬虫并进行数据处理相关的知识,希望对你有一定的参考价值。

“我的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.FromType = v.FromType
	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+爬虫送给大家!

以上是关于我的Go+语言初体验——用Go+写个爬虫并进行数据处理的主要内容,如果未能解决你的问题,请参考以下文章

我的Go+语言初体验——Go+,GoPlus 爬虫第一例

我的Go+语言初体验——Go+ 语言数据类型

我的Go+语言初体验——Go+ 分数型有理数数据类型

我的Go+语言初体验——超详细安装教程

我的Go+语言初体验——整型有理数数据类型

我的Go+语言初体验——在Docker建立一个可以用Go+语言开发的容器环境(以Ubuntu容器为例)