Get小技巧等分列表

问题背景
前天分享了一篇《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))

Get小技巧等分列表

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

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

方法1


seqence = list(range(20))

size = 5 #子列表长度

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

print(output)

Get小技巧等分列表
方法2


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

print(chunks(seq, 5))

Get小技巧等分列表
方法3


def chunks(seq,size):

    for i in range(0,len(seq), size):

        yield seq[i:i+size]

Get小技巧等分列表

数据量不大的情况下,选哪一种方法都可以。如果特别大,建议使用方法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)

Get小技巧等分列表

上一篇:轻盈高效的异步访问库grequests库


下一篇:python 协程编程之gevent