2021-04-07 python爬虫自学——异步爬虫

本文探讨了如何在爬虫中利用异步编程提高性能,介绍了多线程、线程池和协程的不同实现方式,重点讲解了协程和事件循环在实际应用中的优势。通过实例展示了如何使用asyncio库实现单线程+异步和事件循环的高效爬取技术。
摘要由CSDN通过智能技术生成
import time
#使用单线程串行方式执行
def get_page(str):
    print("正在下载:",str)
    time.sleep(2)
    print("下载成功:",str)
name_list=['xiaozi','aa','bb','cc']

start_time=time.time()

for i in range(len(name_list)):
    get_page(name_list[i])
end_time=time.time()
print('%d second'%(end_time-start_time))
import time
#导入线程池模块对应的类
from  multiprocessing.dummy import  Pool
#使用线程池方式执行
start_time=time.time()
def get_page(str):
    print("正在下载:",str)
    time.sleep(2)
    print("下载成功:",str)
name_list=['xiaozi','aa','bb','cc']

#实例化一个线程池对象
pool=Pool(4)
#将列表中每一个列表元素传递给get_page进行处理,返回值一定是列表
pool.map(get_page,name_list)

end_time=time.time()
print(end_time-start_time)
高性能异步爬虫:
目的:在爬虫中使用异步实现高性能的数据爬取操作
异步爬虫的方式:
     - 1.多线程,多进程(不建议)
        - 好处:可以为相关阻塞的操作单独开启线程或进程,阻塞操作就可以异步执行
        - 弊端:无法无限制开启多线程或多进程
    - 2.线程池、进程池:
        - 好处:我们可以降低系统对进程或线程创建和销毁的一个频率,从而很好的降低系统的开销。
        - 弊端:池中线程或进程的数量是有上线的
    - 3.单线程+异步携程(推荐)
        evebt_loop:事件循环,相当于一个无限循环,我们可以把一些函数注册到这个时间循环上,
                          当满足某些条件的时候,函数就会被循环执行。
        coroutine:协程对象,我们可以将协程对象注册到事件循环中,它会被事件循环调用。
                        我们可以使用async关键字定义一个方法,这个方法在调用时不会被立即执行,而是返回
                        一个协程对象。
        task:任务,它是对协程对象进一步进行封装,包含了任务的各个状态。
        future:代表将来执行或还没有执行的任务,实际上和task没有本质区别
        async:定义一个协程
        await:用来挂起阻塞方法的执行
#get方法是一个阻塞的方法
import asyncio
async def request(url):
    print("正在请求的url是:",url)
    print("请求成功",url)
#async修饰的函数,调用之后返回的是一个协程对象
c=request('www.baidu.com')
#创建一个事件循环对象
loop=asyncio.get_event_loop()
#协程对象注册到loop中,然后启动loop
loop.run_until_complete(c)
import asyncio
async def request(url):
    print("正在请求的url是:",url)
    print("请求成功",url)
#async修饰的函数,调用之后返回的是一个协程对象
c=request('www.baidu.com')
#task的使用
loop=asyncio.get_event_loop()
#基于loop创建一个task对象
task=loop.create_task(c)
print(task)
loop.run_until_complete(task)
print(task)
import asyncio
async def request(url):
    print("正在请求的url是:",url)
    print("请求成功",url)
#async修饰的函数,调用之后返回的是一个协程对象
c=request('www.baidu.com')
#future的使用
loop=asyncio.get_event_loop()
task=asyncio.ensure_future(c)
print(task)
loop.run_until_complete(task)
print(task)
import asyncio
async def request(url):
    print("正在请求的url是:",url)
    print("请求成功",url)
#async修饰的函数,调用之后返回的是一个协程对象
c=request('www.baidu.com')
def callback_func(task):
    print(task.result())
#绑定回调
loop=asyncio.get_event_loop()
task=asyncio.ensure_future(c)
#将回调函数绑定到任务对象中
task.add_done_callback(callback_func)
loop.run_until_complete(task)
import asyncio
import time
def request(url):
    print("正在下载",url)
    #在异步协程中如果出现了同步模块相关的代码就无法实现异步
    #当在asyncio中出现阻塞操作必须手动挂起
    time.sleep(2)
    print("下载完毕",url)
start = time.time()
urls=[
    "www.baidu.com",
    "www.sogou.com",
    "www.douban.com"
]
#任务列表:存放多个任务对象
stacks=[]
for url in urls:
    c = request(url)
    task = asyncio.ensure_future(c)
    stacks.append(task)
loop = asyncio.get_event_loop()
#需要将任务列表封装到wait中,不可以直接使用stacks
loop.run_until_complete(asyncio.wait(stacks))

print(time.time()-start)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值