[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并发爬虫版本的演化过程. 那么在演化之前,当然是先跑通一下单任务版本的架构. 正如人走路之前是一定要学会爬走一般. 首先看一下单任务版本的爬虫架构,如下: 这是单任务版本爬虫的 ...
随机推荐
- 【POJ】【1821】Fence
DP/单调队列优化 题意:k个人粉刷总长为n的墙壁(或者说栅栏?),每个人有一个必刷点s[i](这个人也可以一点也不刷,如果刷就必须刷这个点),最大粉刷长度l[i](必须是连续粉刷一段),和粉刷一格的 ...
- Apache环境.htaccess伪静态301跳转(www与不带www)
一般而言,我们使用的301跳转就是WWW与不带WWW域名之间的跳转,用行话说就是权重要归一.对于我们使用Apache环境的来说其实相对nginx比较简单,因为只需要我们在网站根目录有.htaccess ...
- Matlab命令系列之目录操作
Matlab命令系列之目录操作 filesep 用于返回当前平台的目录分隔符,Windows是反斜杠(),Linux是斜杠(/).有时此命令结合ispc命令使用,可以灵活的设置目录分割符. fullf ...
- .Net 命名(委托,事件==)
委托及参数命名: public delegate void ClickedEventHandler(object sender, ClickedEventArgs e); ClickedEventHa ...
- SEO网站优化方案
学习许多前辈的经验,看到一些比较有价值的seo优化方案,特记录一下,对照自己的操作之路,新人也可借鉴一二,下面是从卢松松博客看到的文章.高手直接跳过,请勿喷水. 一个完整的SEO优化方案主要由四个小组 ...
- javascript中的JSON序列化与反序列化
简单粗暴上代码: function create() { this.name = "jack"; this.sex = "man"; } create.prot ...
- Python 融于ASP框架
一.ASP的平反 想到ASP 很多人会说 “asp语言很蛋疼,不能面向对象,功能单一,很多东西实现不了” 等等诸如此类. 以上说法都是错误的,其一ASp不是一种语言是 微软用来代替CGI的一种web框 ...
- oracle连接数据
1.源代码 string connString = "User ID=scott;Password=yanhong;Data Source=(DESCRIPTION = (ADDRESS_L ...
- Eclipse项目的导入跟导出
1.导入项目 当下载了包含Eclipse 项目的源代码文件后,我们可以把它导入到当前的Eclipse 工作区然后编辑和查看.点击菜单File > Import,然后在弹出的Import 对话框中 ...
- haproxy重启
ps -aux | grep haproxy.cfg sudo kill -9 pidsudo /data/tools/haproxy/sbin/haproxy -f /data/tools/hapr ...