关于爬虫限制并发数我竟然用阻塞来实现 20220324编程日记

不是,就挺离谱的。

看了一眼之前写的的爬虫框架。

发现之前实现限制并发数的方法是暂停go routine, 如下所示,就纯纯的等待有空余的位置了,然后继续执行Fetch

1
2
3
4
5
6
7
func (e *Engine) FetchTentacle(tentacle Tentacle) *TentacleResult {
err := e.limiter.WaitN(e.context, 1)
<-e.waitChan
result, _ := Fetch(tentacle, e.requestFunc, e.ReqHandlers, e.RespHandlers)
e.waitChan <- 1
return result
}

离谱在于,如果我有10000个页面要分析,这个东西的实现方式是先创建10000个goroutine,然后等一个goroutine结束了,再挑选新的goroutine执行。

也就是说,如果有N个页面要爬,程序会同时创建N个goroutine............

虽然goroutine确实不怎么耗资源。但是现在一看怎么这么sb啊,为啥不直接用queue。完全不理解当时是怎么想的.

把我自己给整尬了

ps:

和群友吹水的时候突然想起来之前用这个框架做的一个动漫爬虫确实遇到了由这个引起的问题。

之前爬动漫网站,一开始是直接把所有的页面丢进去然后执行,但是不知道为啥,一直出panic,我也找不到问题。

然后我选择每隔10000次请求就暂停,等待这10000次请求完成再继续执行 (如下代码所示),然后这个panic就不再出现了。

1
2
3
4
5
6
7
8
9
10
func (c *MixsiteCrawler) Start()  {
for c.StartID <= c.EndID {
c.InfoEngine.FetchAsync(fmt.Sprintf("http://www.susudm.com/acg/%s/",c.parseId()))
c.StartID ++
if c.StartID % 10000 == 0 {
fmt.Println("wait 10000 to complete")
c.Wait()
}
}
}

现在再看,估计就是goroutine创建太多的原因了。