- 高性能异步爬虫
def get_content(url): print('正在爬取:',url) # get方法是一个阻塞的方法 response=requests.get(url,headers=headers) if response.status_code==200: return response.content def parse_content(content): print('响应数据的长度为:',len(content)) for url in urls: content=get_content(url) parse_content(content)
- 异步爬虫的方式
-
多线程,多进程:
好处:可以为相关阻塞的操作单独开启线程或者进程,阻塞操作就可以异步执行
弊端:无法无限制的开启多线程或者多进程 -
线程池、进程池
好处:我们可以降低系统对进程或者线程创建和销毁的一个频率频率,从而很好的降低系统的开销。
弊端:池中线程或者进程的数量是有上线的- 线程池处理的是阻塞且耗时的操作
import time # 导入线程池对应的类 from multiprocessing.dummy import Pool def get_page(str): print('正在下载:'str) time.sleep(2) print('下载成功:',str) start_time=time.time() name_list=['aa','bb','cc','dd'] # 实例化一个线程池,创建四个线程 pool=Pool(4) # 将列表中每一个列表元素传递给get_page进行处理 # name_list为列表或者字典,作为调用函数的参数传入,此时可认为传入的参数为name_list的遍历传入 pool.map(get_page,name_list) print(time.time()-start_time) # 线程池关闭 pool.close() pool.join()
- 线程池处理的是阻塞且耗时的操作
-
单线程+异步协程:
-
event_loop:时间循环,相当于一个无限循环,我们可以把一些函数注册到这个时间循环中,当满足某些条件时,函数就会被循环执行。
-
coroutine:协程对象,我们可以将协程对象注册到事件循环中,它会被事件循环调用。可以使用async关键字定义一个方法,这个方法在调用时不会立即被执行,而是返回一个协程对象
-
task:任务,它是对协程对象的进一步封装,包含任务的各个状态
-
future:代表将来执行或还没有执行的任务,实际上和task没有本质区别
-
async:定义一个协程
-
await:用来挂起阻塞方法的执行
import asyncio async request(url): print('正在请求的url:',url) print('请求成功:',url) return url # async修饰的函数,调用之后返回一个协程对象 c=request('www.baidu.com') ''' # 创建一个事件循环对象 loop=asyncio.get_event_loop() # 将协程对象注册到loop中,然后启动loop loop.run_until_complete(c) ''' ''' # task的使用 loop=asyncio.get_event_loop() # 基于loop创建一个task对象 task=loop.create_task(c) # 此时未执行 loop.run_until_complete(task) # 此时已执行 ''' ''' # future的使用 loop=asyncio.get_event_loop() task=asyncio.ensure_future(c) # 此时未执行 loop.run_until_complete(task) # 此时已执行 ''' def callback_func(task): # result返回的是任务对象中封装的协程对象对应函数的返回值 print(task.result()) # 回调绑定 loop=asyncio.get_event_loop() # 创建封装协程对象对应函数 task=asyncio.ensure_future(c) # 将回调函数绑定到任务对象中 # 执行成功后,就会调用回调函数,任务对象作为参数 task.add_done_callback(callback_func) loop.run_until_complete(task)
-
-
多任务协程
async def request(url): print('正在下载:',url) # 异步写成中如果出现了同步模块相关的代码,那么就无法实现异步 # time.sleep(2) # 当在asyncio中遇到阻塞操作必须进行手动挂起 await asyncio.sleep(2) print('下载完毕:',url) start=time.time() urls=[ 'www.baidu.com', 'www.sogou.com', 'www.doubanjia.com' ] # 任务列表:存放多个任务对象 tasks=[] for url in urls: c=request(url) task=asyncio.ensure_future(c) tasks.append(task) loop=asyncio.get_event_loop() # 需要将任务列表封装到wait中 loop.run_until_complete(asyncio.wait(tasks)) print(time.time()-start)
-
- 异步爬虫的方式
异步爬虫
最新推荐文章于 2024-03-31 23:26:58 发布