文档章节

GO笔记:解决爬虫限制http并发数量的问题

吾爱
 吾爱
发布于 2017/06/09 10:56
字数 656
阅读 507
收藏 0
Go

假设目标网站结构是:列表页 + 内容页

列表页url是规律的,如 http://DOMAIN/list/page/1

计划采集 1-4000 页,每页10条内容,一共40000个内容页。

假设按照深度优先的采集策略,即按照每抓取一个列表页,提取内容页url,紧接着抓取内容页并提取内容,然后入库。

首先第一步,采集入口,我们使用for循环,为每个列表页创建一个线程去采集。

for n:=1;n<=4000;n++ {
    go CrawlList(fmt.Sprintf("http://DOMAIN/list/page/%d"), n)
}

CrawlList 来抓取列表页,并创建内容页的抓取请求

func CrawlList(listurl string) {
    // http抓取列表页源码, 假设这里封装了个函数, 内部也是异步的,返回一个channel用于接收结果
    ch := HtmlGet(listurl)
    html <- ch
    //提取内容页url,可以使用正则或者 goquery等包 过程省略...
    go CrawlContent(contentUrl)    
}

func CrawlContent(contentUrl string) {
    //抓取内容页源码
    ch := HtmlGet(contentUrl)
    html <- ch
    //提取内容页内容,并入库,过程略    
}

大致过程就是这样,现在问题来了,对方站点限制了访问频率,如果并发过高,会被对方防火墙拦截。所以我们首先要对 HtmlGet 增加并发限制,代码大致原理如下

//创建一个带缓冲的channel,容量为10 , 支持10个并发
var conlimit = make(chan bool, 10) 
func HtmlGet(addr string) chan string {
    conlimit <- true
    ch := make(chan string)
    go func(){
        defer func(){ <-conlimit }()
        //http请求过程略,假设内容保存到 res ,最终通过ch提供消费
        ch <- res    
    }()
    return ch
}

这样,我们可以针对http请求限制同时最多10个并发。

然而还有一个问题,因为我们是深度采集的,所以,一开始我们创建了4000个goroutine采集列表页,那么每个goroutine中都会调用 GetHtml 函数去抓取列表页内容,等于必须等到所有列表页几乎都请求过,才会轮到内容页的采集,在这之前,所有已经请求成功的列表页都会占着内存,等待内容页采集成功。

所以,在第一步我们也需要限制一下,每次最多采集10个列表页,这样10个列表页抓取成功了,会立即处理下面的内容页,也就是最多 10*10个goroutine,不会占用太多内存。

listconlimit := make(chan bool, 10) 
for n:=1;n<=4000;n++ {
    listconlimit <- true
    go func(n int){
        defer func(){ <- listconlimit }()
        CrawlList(fmt.Sprintf("http://DOMAIN/list/page/%d"), n)    
    }(n)
}

注: 以上代码仅视为伪代码,不能直接运行。

-完-

© 著作权归作者所有

吾爱
粉丝 142
博文 272
码字总数 91680
作品 0
后端工程师
私信 提问
加载中

评论(0)

面试:Semaphore(信号量)的成长之路

2019最寒冷,面试跳槽不能等 马上就3月份了,所谓的金三银四招聘季。2019年也许是互联网最冷清的一年,很多知名的大型互联网公司都裁员过冬。当然也有一些公司还在持续招人的,比如阿里就宣称...

尹吉欢
2019/02/25
0
0
WCF技术剖析之九:服务代理不能得到及时关闭会有什么后果?

我们想对WCF具有一定了解的人都会知道:在客户端通过服务调用进行服务调用过程中,服务代理应该及时关闭。但是如果服务的代理不等得到及时的关闭,到底具有怎样的后果?什么要关闭服务代理?...

长平狐
2012/09/04
184
0
Nodejs爬虫进阶=>异步并发控制

之前写了个现在看来很不完美的小爬虫,很多地方没有处理好,比如说在知乎点开一个问题的时候,它的所有回答并不是全部加载好了的,当你拉到回答的尾部时,点击加载更多,回答才会再加载一部分...

飞翔的熊blabla
2019/04/05
0
0
网络爬虫引擎 simspider 更新至 v2.2.1

ver 2.2.1 2015-02-09 calvin * 修正了入口网址的内部自动补全问题 * 修正了删除请求队列后没有重置结果指针的安全编码问题 * 修正了WINDOWS平台的编译问题 ------------------------------...

calvinwilliams
2015/02/09
3.2K
2
【充电】《Nginx核心知识100讲》 preaccess阶段:连接限制limit_conn模块、请求限制limit_req模块

极客专栏《Nginx核心知识100讲》55-56小节的笔记 55 | preaccess阶段:对连接做限制的limit_conn模块 在preaccess阶段限制用户并发连接数的limitconn模块。上一节讲到匹配location,匹配到之...

言十年
2019/01/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Paragon NTFS for Mac(Mac读写ntfs磁盘工具) v15.5.106

Paragon NTFS for Mac(Mac读写ntfs磁盘工具)。它专门开发用来弥补Windows和Mac OS X之间的不兼容性,通过在Mac OS X系统下提供对任何版本的NTFS文件系统完全的读写访问服务来弥合这种不兼容性...

麦克W
10分钟前
5
0
DeepFaceLab上云之滴滴云使用全攻略!

以下内容为转载,转载出处请注意文末。 几天前写了一遍关于云服务器文章,简单的说了下目前国内有些云GPU,大概做了一个价格比较,不少人想要尝试下,但是不知道如何操作。今天就来说说具体操...

滴滴云
14分钟前
9
0
面试官问:cookie是什么?session是什么?,以及它们之间的区别

JavaWeb这个时间有点久了,不能学了前面忘后面,是时候总结一下了 Cookie cookie由服务器生成,发送给浏览器,保存在浏览器上。 cookie生命周期 会话级别: 本次浏览器关闭 保存在 浏览器内存...

庭前云落
20分钟前
7
0
NIO

行者终成事
22分钟前
24
0
多线程 ReentrantLock 中 Lock,tryLock,lockInterruptibly

链接:https://www.zhihu.com/question/36771163/answer/68974735 ReentrantLock 锁有好几种,除了常用的lock ,tryLock ,其中有个lockInterruptibly 。 先把API粘贴上来 lockpublic voi...

moon888
26分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部