[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并发爬虫版本的演化过程. 那么在演化之前,当然是先跑通一下单任务版本的架构. 正如人走路之前是一定要学会爬走一般. 首先看一下单任务版本的爬虫架构,如下: 这是单任务版本爬虫的 ...
随机推荐
- spring framework项目源码github托管地址
方法一:直接下载,github托管地址:http://repo.spring.io/simple/libs-release-local/org/springframework/spring/ 方法二: ...
- JDBC编程步骤
JDBC编程步骤 加载数据库驱动. 通常使用Class类的forName()静态方法来加载驱动. Class.forName(driverClass) dirverClass: mysql---Cla ...
- CocoaPods 使用手册
CocoaPods 使用手册 CocoaPods 使用手册 ...
- Python编程指南 chapter 1
1.python使用方括号[]来存取一个序列中的某个数据项,像字符串.列表等包含若干数据项的序列都采用这种方法. 2.强制类型转换,int('24234'),str(235) 3.python中没有变 ...
- 哪些问题困扰着我们?DevOps 使用建议
[编者按]随着 DevOps 被欲来越多机构采用,一些共性的问题也暴露出来.近日,Joe Yankel在「Devops Q&A: Frequently Asked Questions」一文中总 ...
- win7桌面便签。自带的
新建WIN7下的桌面便签小程序 桌面—>新建 快捷方式-> 输入%windir%\system32\StikyNot.exe
- jmeter 异步子请求测试随笔
好久没写技术类的博客了,都不知道自己都在忙啥.... 最近陆续遇到了一些异步子请求的测试需求,比如打开某一个页面A,A页面里的js会再调用B,C,D,E等请求,针对这个页面的测试,我最近做了一些思考: ...
- copy_to_user,copy_from_user,get_user,put_user函数比较
copy_to_user,copy_from_user,get_user,put_user函数比较 copy_to_user -- Copy a block of data into user sp ...
- 8 simple things that will make you sexy
8 simple things that will make you sexy8种方法教你不动声色的性感What makes a women sexy? Is it her body? Is it t ...
- Centos环境下部署游戏服务器-软件安装
这篇文章主要介绍一下游戏服务器需要安装的软件和需要修改的配置.现介绍下项目,本项目服务器端是c++ + mysql组合,客户端是as写的,需要安装的服务为Mysql,Php,Apache, 以及一个n ...