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

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)

结果:

511dcaf338b4a4a509a34893b9eacb73.png

图片.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)

结果:

dd040584f357e5fb021f70a653bac0fd.png

图片.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)

结果如下:

9047ddc9836113164e97c91e999b1409.png

图片.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)

执行结果:

bc080dc02b96f98799cc232e64abbb4d.png

图片.png

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值