[Golang]实习最后一天小纪念+并发爬虫小练习
今天是我在公司实习的最后一天,一个月的时间真的是太短暂了,我非常享受在公司工作的这一个月,在这里Leader和同事们对我的帮助极大地促进了我技术水平的进步和自信心的提升,我发自内心地感谢白山云科技给我这样一个实习的机会,谢谢你们对我的无私帮助(虽然他们可能也看不到…)。
眼看着暑假还剩不到一个月,其实我内心是不想离开这个公司的,但是想到开学以后又要有各种网络赛和区域赛,又有新生的到来,为了校队,我还是离开吧(虽然我回去也没啥卵用…)。
实习期间第一次写函数式的程序,并且第一次完成了一个用于日志分析的分布式程序。还有腾讯的实时监控数据上报的需求的边缘服务器日志收集和汇总的功能,第一次为自己的代码写了测试。第一次与他人真正地合作完成一个项目,虽然到今天下午的时候leader说腾讯给出了新接口,我们分析了一下需求表示要改一大部分东西,不过我是没有机会再做下去了,留给zzb同学吧,估计他看了我的代码要推翻重写了,哈哈。
记得刚来的时候我一直担心leader分配给我任务,我做不好。但是心一横接下来,不管做得好不好,只要用心去做,哪怕结果不尽人意,还是会得到宽容和认可(好吧我现在觉得我写的东西都是一坨shi…)。
人总归有第一次,在随后的磕磕绊绊中学习,直到做出一点微小的贡献。慢慢地,力所能及的地方越来越高,直到自己羽翼丰满,独当一面,这就是奋斗和成长最吸引人的地方了吧。
不知不觉我就要大三了,大学生活已经度过了一半。大一大二的时候总觉得一些具体的技术我没必要深究,于是就全部搁浅。经过这次实习我的心态有了变化,对自己未来的规划也应当再做一些调整了:
多读一些书,在内存管理、并行代码编写上多下一些功夫。算法再优雅但终归是跑在单核上的,并行程序才适合这个时代。
复习一下网络和数据库的内容。
多看一些语言的第三方库,自己造轮子会浪费很多时间。
多尝试写自己没有写过的东西,不要担心自己第一次写不出来,谁都有第一次,第一次也往往不是顺利的。
复习好数学,继续学习机器学习的知识。
刷题是必须持续进行的,帮助我提高思维水平,以便更好地接受其他知识。
系统地学一下Linux,并且和windows说再见。
现在就想起来这么多,等到以后继续补充吧。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
爬虫的需求很简单,就是从paste.ubuntu.com上搞别人贴的代码,然后判断是不是C/C++代码。面临着几个问题需要考虑:
1、paste访问的时间很长,这很影响爬虫和内容处理的效率,这该怎么办:
这个问题我使用了三种方法来解决,第一个是采用并行程序,这个就不多说了,多开几个线程做处理会快些。第二个是预判这个文件的大小,设定一个阈值,保证这个文件超过阈值后一定不是C/C++的题解代码,当然塞一张表除外,不过OJ一般限制65535B,我们可以取一半即30000B。第三个是设置timeout,在golang里就需要手工建立一个client发送get请求了,这里的具体函数如下:
func GetHtml(Url string, MagicNum string) []byte {
timeout := time.Duration(15 * time.Second)
client := http.Client{
Timeout: timeout,
}
request, err := http.NewRequest(http.MethodGet, Url, nil) if err != nil {
log.Errorln(err.Error())
return nil
}
res, err := client.Do(request)
if err != nil {
log.Errorln(err.Error())
return nil
}
result, err := ioutil.ReadAll(res.Body)
if len(result) > 30000 {
return nil
}
res.Body.Close()
if err != nil {
log.Errorln(err.Error())
return nil
}
rd := bytes.NewReader(result)
nd, err := goquery.Parse(rd)
if err != nil {
log.Panicln(err.Error())
}
str := nd.Find("td.code").Text() buf := []byte(str)
return buf
}
GetHtml
2、判断这个html中包含的代码是C/C++代码:
这个我处理得很糙,就是去看看有没有一个#include子串,当然这个子串是可以增加的,不过可能影响效率。希望有更好办法的朋友可以留下你的方法,在此谢谢。
func Judge(buf []byte) bool {
var patterns = []string{
"#include",
}
n := len(patterns)
for i := 0; i < n; i++ {
ok, err := regexp.Match(patterns[i], buf)
if ok {
return true
}
if err != nil {
log.Errorln(err.Error())
return false
}
}
return false
}
Judge
3、并行访问时如何保证访问不冲突:
这个也很好解决,学过操作系统的人都明白可以添加一个mutex来保证一个资源不被同时访问。我这里更新的是一个offset,道理是一样的。这个os.Args[1]和offset都是全局变量,但是只有offset需要写,所以只给它加mutex就行了。
func numGetter(MagicNum string, ch chan int64) {
Num, err := strconv.ParseInt(MagicNum, 10, 64)
if err != nil {
log.Errorln(err.Error())
return
}
ch <- (Num + Offset)
Offset++
}
numGetter
func NumGetter(Num string, ch chan int64) {
for {
mutex.Lock()
numGetter(Num, ch)
mutex.Unlock()
Do(strconv.FormatInt(<-ch, 10))
}
}
NumGetter
最后并行程序,一个go就可以解决~os.Args[2]用于设定线程数。
func main() {
Offset = 0
ch := make(chan int64, 10)
n, err := strconv.ParseInt(os.Args[2], 10, 64)
if err != nil {
log.Errorln(err.Error())
return
}
var i int64
for i = 0; i < n; i++ {
go NumGetter(os.Args[1], ch)
}
time.Sleep(time.Hour)
}
main
这是我第一次尝试用golang写并行的爬虫程序。我从学习写golang到现在有半个月的时间了,是时候找一本书认真学习一下go这个美妙的语言了。现在写的程序都是在翻译自己脑子里用其他语言写好的程序而已,我应该更多地去使用go语言的特性才可以。
ps: 使用了两个go的第三方库:
"github.com/Sirupsen/logrus"
"github.com/opesun/goquery" 附图:
[Golang]实习最后一天小纪念+并发爬虫小练习的更多相关文章
- golang实现并发爬虫三(用队列调度器实现)
欲看此文,必先可先看: golang实现并发爬虫一(单任务版本爬虫功能) gollang实现并发爬虫二(简单调度器) 上文中的用简单的调度器实现了并发爬虫. 并且,也提到了这种并发爬虫的实现可以提高爬 ...
- 基于webmagic的爬虫小应用--爬取知乎用户信息
听到“爬虫”,是不是第一时间想到Python/php ? 多少想玩爬虫的Java学习者就因为语言不通而止步.Java是真的不能做爬虫吗? 当然不是. 只不过python的3行代码能解决的问题,而Jav ...
- 一个python爬虫小程序
起因 深夜忽然想下载一点电子书来扩充一下kindle,就想起来python学得太浅,什么“装饰器”啊.“多线程”啊都没有学到. 想到廖雪峰大神的python教程很经典.很著名.就想找找有木有pdf版的 ...
- nodeJs爬虫小程序练习
//爬虫小程序 var express = require('express'); //superagent是一个http的库,可以发起get和post请求 var superagent = requ ...
- 适合新手的Python爬虫小程序
介绍:此程序是使用python做的一个爬虫小程序 爬取了python百度百科中的部分内容,因为这个demo是根据网站中的静态结构爬取的,所以如果百度百科词条的html结构发生变化 需要修改部分内容. ...
- java网络爬虫爬虫小栗子
简要介绍: 使用java开发的爬虫小栗子,存储到由zookeeper协调的hbase中 主要过程是模拟Post请求和get请求,html解析,hbase存储 源码:https://github.com ...
- 福利贴——爬取美女图片的Java爬虫小程序代码
自己做的一个Java爬虫小程序 废话不多说.先上图. 目录命名是用标签缩写,假设大家看得不顺眼能够等完成下载后手动改一下,比方像有强迫症的我一样... 这是挂了一个晚上下载的总大小,只是还有非常多由于 ...
- Python_爬虫小实例
爬虫小实例 一.问题描述与分析 Q:查询某一只股票,在百度搜索页面的结果的个数以及搜索结果的变化. 分析: 搜索结果个数如下图: 搜索结果的变化:通过观察可以看到,每个一段时间搜索结果的个数是有所变化 ...
- golang实现并发爬虫一(单任务版本爬虫功能)
目的是写一个golang并发爬虫版本的演化过程. 那么在演化之前,当然是先跑通一下单任务版本的架构. 正如人走路之前是一定要学会爬走一般. 首先看一下单任务版本的爬虫架构,如下: 这是单任务版本爬虫的 ...
随机推荐
- 【BZOJ】【3163】【HEOI2013】Eden的新背包问题
多重背包/思路题 多次询问,每次从所有物品中忽略一件,问最大收益…… 这题我用的zyf的一个“暴力”做法,就是先预处理出来g1[i][j]表示1~i号物品花了j块钱的最大价值,g2[i][j]表示i~ ...
- 【BZOJ】【1031】【JSOI2007】字符加密Cipher
后缀数组 当年感觉好神的题现在好像变水了…… 题意其实有点蛋疼……一开始没看懂<_< 将原串复制一遍接在后面,用后缀数组求一下SA,那么SA<n的就是所找到的那n个字符串,然后把它们 ...
- ALAssetsLibrary
ALAssetsLibrary详解 ALAssetsLibrary类是代表系统中整个资源库,使用它可以访问资源库中的资源和保存照片,视频等功能. _library = [[ALAssetsLibr ...
- [REFERENCE] Real-Time-Normal-Map-Dxt-Compression
DXT5N & 3Dc(aka BC5) compression in common code & SIMD: http://mrelusive.com/publications/pa ...
- HDU1004 Let the Balloon Rise(map的简单用法)
Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- 也可以使用如下命令更改您的默认 Shell
也可以使用如下命令更改您的默认 Shell chsh -s /bin/zsh (需要输入您的密码)
- Codeforces Round #231 (Div2) 迟到的解题报告
题目A: 给一个火柴等式,可以从左边移动一根到右边,也可以从右边移到左边,但是不能移动“+”,”=“的火柴, 而且加法里面的数都要大于0(很重要的条件),基本上注意到这点的都过了,没注意的都被HACK ...
- js函数延迟执行
function delay(value){ //全局变量保存当前值 window._myTempDalayValue = value; setTimeout(function(){ //延时之后与全 ...
- MYSQL注入天书之数据库增删改介绍
Background-4 增删改函数介绍 在对数据进行处理上,我们经常用到的是增删查改.接下来我们讲解一下mysql 的增删改.查就是我们上述总用到的select,这里就介绍了. 增加一行数据.Ins ...
- 很不错的文章---【问底】徐汉彬:亿级Web系统搭建——单机到分布式集群
[导读]徐汉彬曾在阿里巴巴和腾讯从事4年多的技术研发工作,负责过日请求量过亿的Web系统升级与重构,目前在小满科技创业,从事SaaS服务技术建设. 大规模流量的网站架构,从来都是慢慢“成长”而来.而这 ...