进程示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 import timefrom multiprocessing import Processdef get_request (url ): print ('正在请求网址的数据:' , url) time.sleep(2 ) print ('请求结束:' , url)if __name__ == "__main__" : start = time.time() urls = ['www.1.com' , 'www.2.com' , 'www.3.com' ] p_list = [] for url in urls: p = Process(target=get_request, args=(url,)) p_list.append(p) p.start() for pp in p_list: pp.join() print ('总耗时:' , time.time() - start)
执行
1 2 3 4 5 6 7 正在请求网址的数据: www.1 .com 正在请求网址的数据: www.2 .com 正在请求网址的数据: www.3 .com 请求结束: www.1 .com 请求结束: www.2 .com 请求结束: www.3 .com 总耗时: 2.026388645172119
线程示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from multiprocessing.dummy import Pool import timefrom threading import Thread start = time.time()def get_requests (url ): print ('正在爬取数据' ) time.sleep(2 ) print ('数据爬取结束' ) urls = ['www.1.com' ,'www.2.com' ,'www.3.com' ,'www.4.com' ,'www.5.com' ] ts = []for url in urls: t = Thread(target=get_requests,args=(url,)) t.start() ts.append(t)for t in ts: t.join()print ('总耗时:' ,time.time()-start)
执行
1 2 3 4 5 6 7 8 9 10 11 正在爬取数据 正在爬取数据 正在爬取数据 正在爬取数据 正在爬取数据 数据爬取结束 数据爬取结束 数据爬取结束 数据爬取结束 数据爬取结束总耗时: 2.0125858783721924
线程池
线程预先被创建并放入线程池中,同时处理完当前任务之后并不销毁而是被安排处理下一个任务,因此能够避免多次创建线程,从而节省线程创建和销毁的开销,能带来更好的性能和系统稳定性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from multiprocessing.dummy import Pool import time urls = ['www.1.com' ,'www.2.com' ,'www.3.com' ,'www.4.com' ,'www.5.com' ]def get_reqeust (url ): print ('正在请求数据:' ,url) time.sleep(2 ) print ('请求结束:' ,url) start = time.time() pool = Pool(5 ) pool.map (get_reqeust,urls)print ('总耗时:' ,time.time()-start) pool.close()
执行
1 2 3 4 5 6 7 8 9 10 11 12 正在请求数据:正在请求数据: www.2 .com www.1 .com 请求结束: 请求结束: www.1 .com www.2 .com 正在请求数据: www.3 .com 正在请求数据: www.4 .com 请求结束: www.4 .com 正在请求数据: www.5 .com 请求结束: www.3 .com 请求结束: www.5 .com 总耗时: 6.045103311538696
协程示例 回调函数用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import asyncioimport timeasync def get_request (url ): print ('正在请求的网址是:' ,url) time.sleep(2 ) print ('请求网址结束!' ) return 123 c = get_request('www.1.com' ) task = asyncio.ensure_future(c)def task_callback (t ): ret = t.result() print ('我是回调函数,我被执行了,t.result()返回的结果是:' ,ret) task.add_done_callback(task_callback) loop = asyncio.get_event_loop() loop.run_until_complete(task)
执行
1 2 3 正在请求的网址是: www.1.com 请求网址结束!我是回调函数,我被执行了,t.result()返回的结果是: 123
多任务示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import asyncioimport time start = time.time()async def get_request (url ): print ('正在请求的网址是:' ,url) await asyncio.sleep(2 ) print ('请求网址结束!' ) return 123 urls = [ 'www.1.com' ,'www.2.com' ,'www.3.com' ] tasks = [] for url in urls: c = get_request(url) task = asyncio.ensure_future(c) tasks.append(task) loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks))print ('总耗时:' ,time.time()-start)
执行
1 2 3 4 5 6 7 正在请求的网址是: www.1.com 正在请求的网址是: www.2.com 正在请求的网址是: www.3.com 请求网址结束! 请求网址结束! 请求网址结束!总耗时: 2.006136417388916
aiohttp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 import asyncio import time import aiohttp # import requests from lxml import etree start = time.time() urls = [ 'http://127.0.0.1:5000/bobo', 'http://127.0.0.1:5000/jay', 'http://127.0.0.1:5000/tom' ] #发起网络请求,爬取网页完整数据 async def get_request(url): #不可以出现不支持异步模块的代码 #requests是不支持异步,更换一个支持异步的网络请求的模块(aiohttp) # response = requests.get(url=url) # page_text = response.text # return page_text #aiohttp进行网络请求的代码操作 #1.创建一个请求对象:sess async with aiohttp.ClientSession() as sess: #2.使用请求对象发起请求 #aiohttp发起请求的代码操作和requests几乎一致,唯一不一致的地方是,使用代理的参数proxy="http://ip:port" async with await sess.get(url=url) as response: #text()获取字符串形式的响应数据 #read()获取二进制形式的响应数据 #json()和以前的作用一致 page_text = await response.text() return page_text tasks = [] def parse(t): #数据解析 page_text = t.result() tree = etree.HTML(page_text) text = tree.xpath('//a[@id="feng"]/text()')[0] print(text) for url in urls: c = get_request(url) task = asyncio.ensure_future(c) #给任务对象绑定回调函数用于数据解析 task.add_done_callback(parse) tasks.append(task) loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks)) print('总耗时:',time.time()-start)