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

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

准备工作

首先,让我们明确一下需要的准备工作。我们将使用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日

相关推荐

  • 自动获取Steam限时免费游戏信息并实时推送教程

    假设你是一位热爱玩游戏的玩家,而且还热衷于追踪Steam平台上的限时免费游戏优惠。你不想错过任何一个免费游戏的机会,因此你希望能够及时获取到这些信息,并在游戏免费期间立刻领取。但是,为了获取这些信息,你不…

    2023年9月21日
    00
  • 使用Python和CCXT实现马丁格尔策略:虚拟货币量化交易赚钱指南

    虚拟货币市场的高波动性和潜在利润吸引了众多投资者的兴趣。然而,要在这个市场中稳定赚钱并不容易。在这篇教程中,我们将介绍如何使用Python和CCXT库实现马丁格尔策略,这是一种量化交易策略,可以帮助您在虚拟货…

    2023年12月28日
    00
  • 如何将Python Web应用部署到Azure应用服务

    欢迎来到本教程!在这里,你将学习如何将你的Python Web应用(可以是Django或Flask)部署到Azure应用服务。Azure应用服务是一项完全托管的Web托管服务,支持在Linux服务器环境中托管的Python应用。让我们开始吧! …

    2023年9月19日
    00
  • 如何结合OpenAI等大语言模型,使用Python开发虚拟货币交易机器人

    在虚拟货币市场中,随着交易的日益复杂和数据量的增加,传统的交易方法可能不再足够。为了更好地理解市场趋势、制定有效的交易策略,以及实现自动化交易,结合强大的大语言模型如OpenAI,以及Python编程,已经成为…

    2023年12月28日
    00
  • 如何选择Python中的本地键值存储库

    在编程的世界里,有时我们需要在本地存储一些数据,以便后续使用。通常情况下,我们会使用各种配置文件,如INI、JSON、TOML、YAML等,来存储这些信息。然而,对于大量数据的存储需求,配置文件并不总是最好的选择。…

    2023年10月4日
    00
  • 如何使用Python自动化抢购京东商品并邮件通知

    在互联网时代,网购已经成为我们生活的一部分。然而,有些热门商品往往在瞬间售罄,让人们很难买到心仪的商品。不过,幸运的是,Python编程语言可以帮助我们自动化抢购京东商品,并通过邮件通知我们是否成功。在这…

    2023年10月24日
    00
  • 选择最佳GUI编程语言和工具,提高开发效率

    王大神,一名充满热情的自由职业者,最近在开发过程中遇到了一个挑战:客户需要一个在Windows平台上能够提供图形用户界面(GUI)的应用程序,并且要求打包成exe文件,而且要尽量避免bug。在一天的时间里,他尝试了…

    2023年11月17日
    00
  • 在Linux和Ubuntu上安装Python和Tkinter教程

    你是否曾经想过在你的Linux或Ubuntu系统上安装Python和Tkinter,以便开始编写GUI应用程序?或许你正在探索开发的世界,想要学习如何在这些操作系统上配置Python环境,那么你来对地方了。 在这篇教程中,我们将带你…

    2023年10月13日
    00
  • 从汇率到Python:如何查询和换算港币对人民币汇率

    有一天,小明计划去香港旅游,但他对港币对人民币的汇率一无所知。他不想在旅行中被坑,所以决定学习如何查询和换算港币对人民币的汇率。在他的学习过程中,他发现了Python这个有趣的工具,可以帮助他轻松查询汇率…

    2023年10月20日
    00
  • 使用OpenAI API创建文本生成教程

    在本教程中,我们将介绍如何使用OpenAI API来生成自然语言文本。OpenAI API提供了强大的自然语言处理能力,可以用于各种应用,如智能助手、内容生成、语言理解等。通过本教程,你将学会如何使用Python代码调用OpenA…

    2024年3月11日
    00