本次我们爬取的是花瓣网图库的照片~
(爬取的代码不过多解释)
不使用协程 来下载180张高清图片:
import asyncio
import aiohttp
import requests
import time
global imageNum, pageUrl, src_list
src_list = []
pageUrl = 1
imageNum = 1
url = 'https://api.huaban.com/boards/78077033/pins?limit=20'
nextUrl = 'https://api.huaban.com/boards/70421988/pins?limit=20&max='
imageUrl = 'https://gd-hbimg.huaban.com/{}_fw658'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54'
}
# 拿到所有图片下载的链接
def get_content(url):
global pool, src_list, pageUrl
# 获取response数据
response = requests.get(url=url)
data = response.json()
# 获取下载页的url
src_list.append(url)
# 获取下一页url
nextPageUrl = nextUrl
pins_list = data['pins']
length = len(pins_list)
print(f'获取第{pageUrl}页...')
pageUrl += 1
if length == 0 or pageUrl == 10:
return
endPinId = data['pins'][length - 1]['pin_id']
# 请求下一页数据
get_content(nextPageUrl + str(endPinId))
pass
# 下载图片
def download(url):
global imageUrl, imageNum
response = requests.get(url)
for imageInfo in response.json()['pins']:
imageSrc = imageUrl.format(imageInfo['file']['key'])
with open(f'图片/{imageNum}.jpg', 'wb') as fp:
fp.write(requests.get(imageSrc).content)
print(f'正在下载第{imageNum}张图片...')
imageNum += 1
if __name__ == '__main__':
start_time = time.time()
# 获取到下载的src
get_content(url)
# 同步
for src in src_list:
download(src)
end_time = time.time()
print('花费时间:', end_time - start_time)
运行结果如下(最后一部分):
..............
正在下载第176张图片...
正在下载第177张图片...
正在下载第178张图片...
正在下载第179张图片...
正在下载第180张图片...
花费时间: 40.20899534225464
可见下载一百多张照片也要花费不菲的时间代价
使用协程 来下载180张高清图片:
import asyncio
import aiohttp
import requests
import time
global imageNum, pageUrl, src_list
src_list = []
pageUrl = 1
imageNum = 1
url = 'https://api.huaban.com/boards/78077033/pins?limit=20'
nextUrl = 'https://api.huaban.com/boards/70421988/pins?limit=20&max='
imageUrl = 'https://gd-hbimg.huaban.com/{}_fw658'
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54'
}
def get_content(url):
global pool, src_list, pageUrl
# 获取response数据
response = requests.get(url=url)
data = response.json()
# 下载该页
# download(url)
# 获取下载页的url
src_list.append(url)
# 获取下一页url
nextPageUrl = nextUrl
pins_list = data['pins']
length = len(pins_list)
print(f'获取第{pageUrl}页...')
pageUrl += 1
if length == 0 or pageUrl == 10:
return
endPinId = data['pins'][length - 1]['pin_id']
# 请求下一页数据
get_content(nextPageUrl + str(endPinId))
pass
async def download(url):
global imageUrl, imageNum
response = requests.get(url)
for imageInfo in response.json()['pins']:
imageSrc = imageUrl.format(imageInfo['file']['key'])
# 从阻塞型requests.get 变成 异步型 session.get()
async with aiohttp.ClientSession() as session:
with open(f'图片/{imageNum}.jpg', 'wb') as fp:
async with session.get(imageSrc) as res:
fp.write(await res.content.read())
print(f'正在下载第{imageNum}张图片...')
imageNum += 1
async def main():
tasks = []
# 下载加入协程任务
for src in src_list:
task = asyncio.create_task(download(src))
tasks.append(task)
await asyncio.wait(tasks)
if __name__ == '__main__':
start_time = time.time()
# 获取到下载的src
get_content(url)
# 同步
# for src in src_list:
# download(src)
# 异步
asyncio.run(main())
end_time = time.time()
print('花费时间:', end_time - start_time)
运行结果如下:
....................
正在下载第176张图片...
正在下载第177张图片...
正在下载第178张图片...
正在下载第179张图片...
正在下载第180张图片...
花费时间: 7.4606032371521
我在第一次学习使用协程进行代码测试的时候就被惊人的效率震撼到了,足足缩短了33秒,这带来了极大的效率提升!
协程,是一种比线程更加轻量级的存在,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源,协程仍然是单线程的运行模式。