首页 > 编程语言 >Python 图片并行下载

Python 图片并行下载

时间:2023-09-27 10:34:13浏览次数:37  
标签:Python image 并行 url print path os 下载

需求:有大量图片的url需要将其快速下载到本地
技术点:采用编写并发代码的库asyncio以及基于asyncio实现的HTTP框架aiohttp

pip install asyncio
pip install aiohttp

代码如下:

import json
import os
import requests
import aiohttp
import asyncio


image_save_dir = "images"  # 要将下载的图片保存到的本地文件夹路径
image_url_list = []  # 要下载的image url元素组成的列表

cnt = 0  # 已下载到本地指定位置的图片数量
n_miss = 0  # 下载失败的图片数量
async def download_image(session, url):
    global cnt
    global n_miss
    file_name = os.path.basename(url)
    # 保存图片到指定位置
    file_path = os.path.join(image_save_dir, file_name)
    if not os.path.exists(file_path):
        try:
            async with session.get(url) as response:
                if response.status == 200:
                    # 获取文件名
                    with open(file_path, 'wb') as file:
                        file.write(await response.read())
                    cnt += 1
                    if cnt % 100 == 0:
                        print("已下载{}/{}".format(cnt,len(image_url_list)))
                else:
                    n_miss += 1
                    print(f'下载失败,状态码:{response.status}, 链接:{url}')
        except Exception as e:
            n_miss += 1
            print(f'下载失败,链接:{url}, 错误:{str(e)}')
    else:
        cnt += 1
        if cnt % 100 == 0:
            print("已下载{}/{}".format(cnt,len(image_url_list)))
            print("下载失败: ",n_miss)

async def main():
    async with aiohttp.ClientSession() as session:
        tasks = [download_image(session, url) for url in image_url_list]
        await asyncio.gather(*tasks)
        print("总图片数量: {}".format(len(image_url_list)))
        print("下载成功: {}".format(cnt))
        print("下载失败:{}".format(n_miss))

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

采用上述代码进行并行下载,速度比传统的串行下载提升了好几个数量级(实验了下载20w张图片也很快),但是要注意(1)可能的网络原因导致的后续图片下载失败(在网络连接可以的情况下多运行几次代码即可)以及(2)可能的由于并行等待时间不足等原因导致的图片下载不全(即下载到本地之后,图片有损无法打开),此时,建议再用以下代码进行检查并串行下载完之前下载后有损的图片:

import json
import os
from PIL import Image
import requests

# 一、检查图片下载情况
image_path_list = []  # 需要检查的图片路径组成的列表

err_imgs = []  # 下载到本地但是无法打开的图片名称组成的列表
n_miss = 0  # 没下载到本地的图片数量
n_err = 0  # 下载到本地但是无法打开的图片数量
for i in range(len(image_path_list)):
    image_path = image_path_list[i]
    try:
        image = Image.open(image_path)
    except:
        err_imgs.append(os.path.basename(image_path))
        n_err += 1
        # print(image_path)
    if not os.path.exists(image_path):
        n_miss += 1
print("没下载到本地的图片数量: ", n_miss)
print("下载到本地但是无法打开的图片数量: ", n_err)

err_imgs = list(set(err_imgs))
print(err_imgs)

# 二、如果有下载到本地但是图片有损打不开的情况,进行串行下载
if n_err > 0:  
    image_url_list = []  # 待串行下载的图片url列表

    image_save_dir = "save_dir"  # 待下载到本地保存的图片文件夹路径
    if not os.path.exists(image_save_dir):
        os.mkdir(image_save_dir)
        print(image_save_dir + ' maked')
    for image_url in image_url_list:
        response = requests.get(image_url)
        # 检查响应状态码,确保请求成功
        if response.status_code == 200:
            # 获取图像数据
            image_data = response.content
            # 本地保存图像
            with open(os.path.join(image_save_dir, os.path.basename(image_url)), 'wb') as file:
                file.write(image_data)
                print(os.path.join(image_save_dir, os.path.basename(image_url)))
        else:
            print("下载失败,HTTP响应状态码:", response.status_code)

欢迎在评论区给出宝贵意见,交流学习

标签:Python,image,并行,url,print,path,os,下载
From: https://www.cnblogs.com/fzucsx/p/17732086.html

相关文章

  • Python面试高频问题:修改list中某个元素时的坑
    在Python面试中经常会考这样一个题目,遍历列表,如果列表中有某某元素,那么将其替换成"test"。题目看似简单,其实有个坑在里面!从面试结果来看,大多数同学都会这样写:l=["a","b","c"]foriinl:if"a"==i:i="test"print(l)运行后,大家会发现输出的l值还是['a',......
  • python range中的步长必须是整数 numpy则可以是小数
    >>>foriiinrange(1,10,0.1): print(ii)Traceback(mostrecentcalllast):File"<pyshell#4>",line1,in<module>foriiinrange(1,10,0.1):TypeError:'float'objectcannotbeinterpretedasaninteger>>......
  • macOS Sonoma 14 (23A344) 正式版发布,ISO、IPSW、PKG 下载
    macOSSonoma今日推出,全面提升生产力和创意工作流macOSSonoma14(23A344)正式版发布,ISO、IPSW、PKG下载2023年9月26日(北京时间27日凌晨)macOSSonoma正式版现已发布。本站下载的macOS软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,......
  • macOS Sonoma 14 (23A344) 正式版 Boot ISO 原版可引导镜像下载
    macOSSonoma14(23A344)正式版BootISO原版可引导镜像下载2023年9月26日(北京时间27日凌晨)macOSSonoma正式版现已发布。本站下载的macOS软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,或者在虚拟机中启动安装。另外也支持在Windows......
  • Python脚本连接Oracle数据库并验证成功
    #yaml文件存储数据->root\Data\oracle_admin_f_shozaiko.yaml#TestDataforOracleDB:ADMIN->F_SHOZAIKO-name:connecttoOraclerequest:uname:adminupwd:P823!ApoLhost:rf-oms.cbfvvrud0bld.ap-northeast-1.rds.amazonaws.com:1521/rfomsqu......
  • 如何用java代码实现上传文件和下载文件
    如何用java代码实现上传文件:首先创建一个项目创建index.jsp页面如下只要是上传文件就要使用form标签的enctype属性:<!--只要是涉及到上传文件enctype="multipart/form-data"--><formaction="UploadServlet"method="post"enctype="multipart/form-data"> &l......
  • python学习框架
    Python简介与安装Python的历史与特点Python的安装与配置Python基础语法变量与数据类型运算符与表达式控制结构(条件判断与循环)函数与模块错误处理与异常Python数据结构列表(List)元组(Tuple)集合(Set)字典(Dictionary)Python面向对象编程类与对象继承与多态......
  • Python的Selenium库:鼠标滚动和操作弹出窗口
    Selenium是一个用于自动化web应用测试的开源工具。通过Selenium,我们可以模拟真实用户的操作,如点击、输入、滚动页面等,来测试web应用的稳定性和可靠性。PythonSelenium库是Selenium的一个分支,可以方便地与Python语言结合使用。在PythonSelenium库中,元素定位和文本输入是最常用的......
  • 使用PyCharm敲出你的第一行python代码
    首先安装python解释器国内镜像https://registry.npmmirror.com/binary.html?path=python/   找到软件开始安装   然后下载python开发工具https://www.jetbrains.com/pycharm/download/download-thanks.html?platform=windows&code=PCC     ......
  • Python datetime 的坑以及时间处理的经验
    最近遇到一个"bug",就是本地datetime的时间上传到数据库,总发现时间显示不对……经过一番痛苦的排查之后,我发现原来是datetime.now()在获取事件信息时,不会添加当前的时区信息。也就是说,获得的结果虽然时分秒和电脑显示一致,但是时区信息为默认的UTC而非我们真正的UTC+8,因此这......