美文网首页大杂烩,味道好初学者
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