美文网首页大杂烩,味道好初学者
python中用协程(异步)实现map函数,爬虫也可以封装进去,

python中用协程(异步)实现map函数,爬虫也可以封装进去,

作者: 周周周__ | 来源:发表于2019-10-18 10:55 被阅读0次
    1、python中得函数map(),通过加延时发现,是单线程执行,有阻塞,实现如下:
    import time
    
    def A(a):
        time.sleep(0.5)
        c = a + 11
        return c
    
    b = [1, 2, 34, 5, 3, 4, 6, 8, 9]
    start = time.time()
    c = map(A, b)
    print(list(c))
    end = time.time()
    print(end-start)
    
    
    结果: 图片.png
    2、自己实现map()函数功能,如下:
    import time
    
    
    def map(fun, lis):
        for i in lis:
            yield fun(i)
    
    
    def A(a):
        time.sleep(0.5)
        c = a + 11
        return c
    
    
    b = [1, 2, 34, 5, 3, 4, 6, 8, 9]
    start = time.time()
    c = map(A, b)
    print(list(c))
    end = time.time()
    print(end-start)
    
    
    结果: 图片.png

    对比发现以上是完全模拟map函数,没有差错。

    我就在想能不能通过异步实现map()的方法,通过传入列表值,并加步长控制并发量,来实现。这样得话就可以通过map()实现并发爬虫,而且十分好控制。
    实现代码:
    # -*- coding: utf-8 -*-
    from gevent import monkey
    monkey.patch_all()
    import gevent
    import time
    def map(fun, li, step):
        result = []
        liss = [li[i:i + step] for i in range(0, len(li), step)]  # 如果传入指定步长则按照步长规定执行
        for lis in liss:
            g_list = list()
            for i in lis:
                g = gevent.spawn(fun, i)
                g_list.append(g)
            gevent.joinall(g_list)
            for g in (g_list):
                result.append(g.value)
        return result
    def A(a):
        time.sleep(1)
        c = a + 11
        return c
    b = [1, 2, 34, 5, 3, 4, 6, 8, 9]
    start = time.time()
    c = map(A, b, 9)  # 传入指定函数,指定列表, 指定步长。异步执行
    print(list(c))
    end = time.time()
    print(end-start)
    start = time.time()
    b = map(A, b, 1)
    print(b)
    end = time.time()
    print(end-start)
    

    结果如下:


    图片.png
    可以很直观的看出,通过异步执行很简单快速的获得到执行效果。

    同时爬虫本来就是网络Io执行。
    在此可以封装爬虫进行异步执行,还是很方便的。因为在此用于展示,map()有统一的返回值。如果用于爬虫,代码需要稍作修改。
    爬虫展示:

    from gevent import monkey
    monkey.patch_all()
    import gevent
    import time
    import requests
    def map(fun, li, step):
        result = []
        liss = [li[i:i + step] for i in range(0, len(li), step)]   # 如果传入指定步长则按照步长规定执行
        for lis in liss:
            g_list = list()
            for i in lis:
                g = gevent.spawn(fun, i)
                g_list.append(g)
            gevent.joinall(g_list)
            for g in (g_list):
                result.append(g.value)
        return result
    def A(a):
        a = requests.get(a)
        return a.status_code
    b = [ 'https://www.baidu.com/', 'https://www.baidu.com/' 'https://www.baidu.com/','https://www.baidu.com/','https://www.baidu.com/', 
    'https://www.baidu.com/', 'https://www.baidu.com/', 'https://www.baidu.com/',]
    start = time.time()
    c = map(A, b, 8)  # 传入指定函数,指定列表, 并发量为8, 可控制。
    print(list(c))
    end = time.time()
    print(end-start)
    start = time.time()
    b = map(A, b, 1) #并发量为1
    print(b)
    end = time.time()
    print(end-start)
    
    执行结果: 图片.png

    参考连接:https://www.cnblogs.com/russellyoung/p/python-zhi-xie-cheng.html#toc_5

    相关文章

      网友评论

        本文标题:python中用协程(异步)实现map函数,爬虫也可以封装进去,

        本文链接:https://www.haomeiwen.com/subject/bzcbbftx.html