从进程池到线程池:实现高效图片下载

在数字时代,我们每天都能够轻松访问到各种各样的图片,不论是美景、艺术品还是有趣的表情包。然而,有时候我们需要大量的图片数据,例如用于机器学习的训练集或者简单的个人收藏。在这种情况下,如何高效地获取和保存这些图片就成了一个挑战。今天,我将向大家介绍一种使用进程池线程池相结合的方法,以实现高效的图片下载

准备工作

首先,让我们明确一下需要的准备工作。我们将使用Python来完成这个任务,所以确保你已经安装了Python环境。此外,我们还需要以下库:

  • requests:用于发送HTTP请求和获取网页内容。
  • lxml:用于解析HTML文档。
  • multiprocessing:用于创建进程池和进程共享变量。
  • concurrent.futures:用于创建线程池。

确保你已经安装了这些库,如果没有,可以使用pip来安装。

获取图片地址

首先,我们需要获取要下载的图片的地址。在这个例子中,我们将从一个网站上抓取动漫壁纸的图片地址。我们使用了requests库来发送GET请求,然后使用lxml来解析HTML文档,提取出图片的地址。这些地址将被放入一个进程队列中,以便后续的下载。

# 获取图片地址
def get_url(url, que):
    resp = requests.get(url, headers=headers)
    resp.encoding = resp.apparent_encoding
    date = resp.text
    tree = etree.HTML(date)
    list_url = tree.xpath('//ul[@class="clearfix"]/li/a')
    for i in list_url:
        url_img = i.xpath('./img/@src')
        que.put('https://pic.netbian.com' + str(*url_img))  # put写入进程变量队列中
    resp.close()

下载并保存图片

接下来,我们需要编写函数来下载并保存图片。我们使用requests库发送GET请求,然后将图片保存到本地。为了避免文件名冲突,我们可以使用一个共享的数值型变量来为每张图片分配一个唯一的文件名。这个变量会在多个进程之间共享,确保每张图片的文件名都不同。

# 下载并保存图片
def download_ove(url, name):
    try:
        resp = requests.get(url, headers=headers)
        path_img = os.path.join(path, f'{name.value}.jpg')
        with open(path_img, 'wb') as f:
            f.write(resp.content)
        print(f'保存成功{name.value}.jpg')
        name.value += 1  # 数值型进程变量自增
    except Exception as ex:
        print('下载出错', ex)

下载图片的主函数

现在,让我们来编写下载图片的主函数。我们使用了线程池来并发下载图片,这样可以提高下载速度。通过创建一个ThreadPoolExecutor对象,我们可以指定同时运行的线程数量,这里设置为20。然后,我们从进程队列中获取图片地址,并将下载任务提交给线程池处理。

# 获取进程队列中的url并启用线程池下载保存图片
def download_img(que, name):
    # 创建线程池,指定20个线程处理数据
    with ThreadPoolExecutor(20) as t:
        while True:
            try:
                s = que.get(timeout=3)  # 获取进程队列中的数据,等待3秒若是还没获取到数据抛出异常
                t.submit(download_ove, s, name)  # 添加进线程池
            except Exception as ec:
                print(ec)
                break

异常处理

在我们的代码中,我们还加入了异常处理机制。如果下载出现错误,我们会捕获异常并打印出错信息。这有助于我们及时发现问题并进行处理。

# 接收进程池与线程池异常的回调函数
def err_call_back(err):
    print(f'出错啦~ error:{str(err)}')

执行主程序

最后,我们在主程序中执行上述函数。我们首先创建了一个进程共享的队列变量和一个数值型的共享变量,用于存储图片地址和文件名计数。然后,我们根据需要获取多个页面的图片地址,将下载任务提交给进程池,并等待任务完成。这样,我们就能够高效地下载大量图片了。

if __name__ == '__main__':
    if not os.path.exists(path):
        os.mkdir(path)
    que = multiprocessing.Manager().Queue()  # 创建一个进程之间共享的队列变量
    name = multiprocessing.Manager().Value('i', 0)  # 创建一个进程之间共享的数值型变量,'i'表示整型数字,0表示从0开始
    for i in range(1, 4):
        if i != 1:
            url = f'https://pic.netbian.com/4kdongman/index_{i}.html'
        else:
            url = 'https://pic.netbian.com/4kdongman/'
        get_url(url, que)
        #  创建进程池,并将函数添加到进程池内,指定最多开辟1个进程处理数据(开多了怕把网址玩崩)
        with multiprocessing.Pool(1) as pool:
            pool.apply(download_img, args=(que, name))  # 将函数以同步的方式添加进进程池
    pool.close()  # 结束进程池,不在往内添加数据
    pool.join()  # 等待进程池运行结束
    print('结束')

结束语

通过使用进程池和线程池的组合,我们能够高效地下载大量图片,提高了任务的并发性和效率。这种方法对于需要大规模获取图片数据的任务非常有用,例如构建图像数据集或爬取网站上的图片资源。

希望这个教程对你有所帮助,如果你有任何问题或建议,欢迎在评论中留言。祝愿你在图片下载任务中取得成功!

本文由作者 王大神 原创发布于 大神网的AI博客。

转载请注明作者:王大神

原文出处:从进程池到线程池:实现高效图片下载

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 2023年10月14日
下一篇 2023年10月14日

相关推荐

  • 大乐透开奖号码结果分析与Python概率学预测

    曾经有一位名叫小明的彩票爱好者,每周都迫不及待地购买大乐透彩票,希望能够中大奖,实现财富自由的梦想。然而,他经历了长时间的失望,频频未能中奖。直到有一天,他听说了使用Python和概率学可以增加中奖几率的…

    2023年10月20日
    00
  • 如何使用Python爬取豆瓣电影Top250的电影海报

    作为一位电影爱好者,你可能经常关注豆瓣电影上的Top250电影榜单,想要了解哪些电影备受推崇。而且,你可能也希望将一些你喜欢的电影的海报保存下来,以便日后欣赏或分享。但是,手动一个一个点击电影,然后下载海…

    2023年9月21日
    00
  • Python与CCXT:虚拟货币量化交易入门指南

    虚拟货币市场的蓬勃发展吸引了越来越多的投资者,但如何在这个高度波动的市场中获得成功?答案之一是量化交易,而Python和CCXT是您的得力工具。本教程将引导您进入虚拟货币量化交易的世界,学习如何使用Python和CCX…

    2023年12月28日
    00
  • 如何使用Python批量转换不同格式的图片为JPG格式

    在日常工作和生活中,我们可能会遇到需要将多种不同格式的图片批量转换为JPG格式的情况。本教程将向您展示如何使用Python编写代码来实现这一任务,并进一步介绍如何使用PyInstaller将代码打包成可执行文件,以便在…

    2022年12月14日
    00
  • Python中的常用字符串操作技巧

    在计算机编程中,字符串是一个非常常见且重要的数据类型。无论你是初学者还是有经验的开发者,都会经常处理字符串。本教程将介绍一些Python中常用的字符串操作技巧,帮助你更有效地处理和操作字符串数据。 1. 反转…

    2023年10月20日
    00
  • CPU Cache 与读写锁的关系

    在计算机科学领域,CPU Cache(中央处理器缓存)和读写锁(RW Lock)都是非常重要的概念,它们在多进程操作数据时发挥着关键作用。本文将深入探讨CPU Cache和读写锁之间的关系,以及它们在多进程操作数据时的作用和…

    2023年4月9日
    00
  • 如何使用Python自动化RSS订阅、更新和邮件通知

    在信息爆炸的时代,获取最新的新闻、博客文章和内容更新变得至关重要。然而,每天手动检查各个网站的RSS订阅可能会非常繁琐。幸运的是,Python编程语言可以帮助我们自动化这个过程,从而轻松获取最新的信息,并通过…

    2023年10月24日
    00
  • 动态类型语言中如何确定返回值类型:Python实践指南

    在Python的世界中,张三正面临一个挑战。他正在使用一个新的第三方库,但遇到了一个问题:每次调用函数,由于缺乏类型提示,他都不知道返回的数据类型是什么。看源码,但似乎很复杂,IDE没有给出有用的提示。张三开…

    2023年10月9日
    00
  • 揭秘交易情绪分析:你的成功交易利器

    你是否曾想过,在投资和交易的旅程中,能够洞察市场情绪的变化,从而更明智地做出决策?交易情绪分析正是这个领域的一颗璀璨明珠,它利用自然语言处理和机器学习技术,帮助你解读市场的情感波动,无论是乐观、悲观…

    2023年9月27日
    00
  • 从Java到Python:数据分析新征程的启航

    在现代科技领域,数据分析已经成为了一个不可或缺的部分。对于那些原本从事Java编程的开发者来说,转向Python并掌握数据分析技能可能是一项重要的挑战。本文将探讨从Java到Python的转变,以及如何开始学习Python的…

    2023年10月27日
    00