1.协程
重复利用单线程的cpu,对于处于IO操作可能会将程序切换到其他任务上。
2.协程在爬虫应用的模板
#多任务协程的模板
import asyncio
async def download(url):
print('开始下载!')
await asyncio.sleep(3) #换成对应的异步请求 注意不是request.get
print('下载完成!')
async def main():
urls=[ 'http:/123.com', #将网站放入
'http:/234.com',
'http:/234.com',
'http:/234.com',
]
task=[]
for url in urls:
task.append(download(url))
await asyncio.wait(task)
if __name__=='__main__':
asyncio.run(main())
3.下载图片的实例
import asyncio
import aiohttp
import aiofiles
async def aiodownload(url):
name =url.rsplit('/',1)[1] #从右边切,切一次,选第二个
async with aiohttp.ClientSession() as session: #aiohttp.ClientSession()等同于requets
async with session.get(url) as reap: #发送请求 requets.get()
async with aiofiles.open(name,mode='wb') as f: #创建文件 异步操作保存文件
datawrite= await reap.content.read() #异步操作等待读取2进制完成
await f.write(datawrite) #将读取的写入到文本 等待完成
print(name,'over!!!')
async def main():
urls= [
'http://kr.shanghai-jiuxin.com/file/2020/1031/191468637cab2f0206f7d1d9b175ac81.jpg',
'http://kr.shanghai-jiuxin.com/file/2020/1031/d7de3f9faf1e0ecdea27b73139fc8d3a.jpg',
'http://kr.shanghai-jiuxin.com/file/2020/1031/3ed27e5aedc2673755bf3327e9dcc13b.jpg'
]
task=[]
for url in urls:
d = asyncio.create_task(aiodownload(url)) #创建任务
task.append(d) #添加任务
await asyncio.wait(task) #等待所有的下载任务完成
if __name__=='__main__':
#asyncio.run(main())
loop = asyncio.get_event_loop() #以上运行异步操作 会报错 改为下面这样写法
loop.run_until_complete(main())
4.百度小说-协程实例
本程序不作为实际下载小说的实例,因为文档加密了所以就没有下载对应的文本,只下载了文本链接。
import requests
import asyncio
import aiohttp
import aiofiles
async def aiodownload(chapterid,title):
url = 'https://novelapi.baidu.com/boxnovel/cors'
params = {
'uid': '',
'boxnovelTimeStampNow': 1641730100555,
'trace_log': 'undefined',
'action': 'novel',
'type': 'content',
'osname': 'wise',
'data': '{"book_id":"4306063500","chapter_id":'+chapterid+'}' #书的id 和章节id
}
async with aiohttp.ClientSession() as session: #aiohttp.ClientSession()等同于requets
async with session.get(url,params=params) as reap: #发送请求 requets.get()
respconter = await reap.json()
async with aiofiles.open(f'{title}.txt',mode='w',encoding='utf-8') as f: #创建文件 异步操作保存文件
await f.write(title+respconter['data']['url']) #将读取的写入到文本 等待完成
print(title,'over!!!')
async def main():
#读取书本章节id
bookID='4306063500' #西游记
chapterids= []
for pageNum in range(1,4):
url ='https://boxnovel.baidu.com/boxnovel/wiseapi/chapterList'
params= {
'bookid': bookID,
'pageNum': pageNum,
'order': 'asc',
'site':'' }
resp = requests.get(url,params=params)
respconter = resp.json()
resp.close()
pages = respconter['data']['chapter']['chapterInfo']
task=[]
for page in pages:
#print([page['chapter_title'],page['chapter_id']])
d = asyncio.create_task(aiodownload(page['chapter_id'],page['chapter_title'])) #创建任务
task.append(d) #添加任务
await asyncio.wait(task) #等待所有的下载任务完成
if __name__=='__main__':
#asyncio.run(main())
loop = asyncio.get_event_loop() #以上运行异步操作 会报错 改为下面这样写法
loop.run_until_complete(main())
5.总结
协程还是比较难理解的,尤其是最后的百度小说,我搞晕了。