查看原文
其他

Get小技巧等分列表

2018-01-12

作者 大邓

问题背景

前天分享了一篇gevent:异步理论与实战的文章,我们可以对待爬网站实时异步访问,速度会大大提高。测试的时候只是小批量爬取12个词语的信息,也就是说一瞬间我们对网站访问了12次,这还没啥问题。

words = ['good','bad','cool',         'hot','nice','better',         'head','up','down',         'right','left','east']        
def asynchronous(words):    
   events = [gevent.spawn(fetch_word_info,word) for word in words]    
   wordinfos = gevent.joinall(events)    
   for wordinfo in wordinfos:        #获取到数据get方法        print(wordinfo.get())    
   end = time.time()    
   print("异步运行时间: %s 秒"%str(end-start))


但是客户让我爬10000+个词语的音标及注释信息,如果使用gevent的话,那几秒钟之内就给网站一股脑的发请求,说不定网站就把握封了。我们要做有良知的爬虫,写一个类似于寄生虫的爬虫,如果寄主挂掉了,对寄生虫也不是啥好事,你说是不是。

解决思路

将列表等分为若干个子列表,分批爬取。举例我们有一个数字列表(0-19),要均匀的等分为4份,也就是子列表有5个数。下面是我在stackoverflow查找到的列表等分方案:

方法1

seqence = list(range(20))

size = 5 #子列表长度

output = [seqence[i:i+size] for i in range(0, len(seqence), size)]

print(output)

方法2

chunks = lambda seq, size: [seq[i: i+size] for i in range(0, len(seq), size)]

print(chunks(seq, 5))

方法3

def chunks(seq,size):    
   for i in range(0,len(seq), size):        
       yield seq[i:i+size]

数据量不大的情况下,选哪一种方法都可以。如果特别大,建议使用方法3.

回到爬虫情景,解决问题

已经找到解决办法了,那么我们动手实现

def asynchronous(words):    start = time.time()    print('异步开始了')    
   chunks = lambda seq, size: [seq[i: i + size] for i in range(0, len(seq), size)]    
   for subwords in chunks(words,3):        
       events = [gevent.spawn(fetch_word_info, word) for word in subwords]        
       wordinfos = gevent.joinall(events)        
       for wordinfo in wordinfos:            # 获取到数据get方法            print(wordinfo.get())        
       time.sleep(1)    
       end = time.time()    print("异步运行时间: %s 秒" % str(end - start))


asynchronous(words)

数据采集

文本处理分析

图片数据处理

其他


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存