Python爬虫下载图片,不使用协程 与 使用协程的效率对比

本次我们爬取的是花瓣网图库的照片~

(爬取的代码不过多解释)

不使用协程 来下载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秒,这带来了极大的效率提升!

协程,是一种比线程更加轻量级的存在,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源,协程仍然是单线程的运行模式

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值