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
网友评论