Python - 循环浏览大列表并快速下载图像

标签 python performance loops download

所以目前我有这段代码,它完美地按照我的预期工作。

import urllib.request
from tqdm import tqdm

with open("output.txt", "r") as file:
    itemIDS = [line.strip() for line in file]

x = 0

for length in tqdm(itemIDS):
    urllib.request.urlretrieve(
        "https://imagemocksite.com?id="+str(itemIDS[x]), 
        "images/"+str(itemIDS[x])+".jpg")
    x += 1

print("All images downloaded")

我四处寻找,发现的解决方案并不是我真正想要的。我的速度是 200mbp/s,所以这不是我的问题。

我的问题是我的循环每秒迭代 1.1 - 1.57 次。我想加快速度,因为我要下载超过 5000 张图像。它们每个也大约 1-5kb。

此外,如果有人有任何一般的代码提示,我将不胜感激!我正在学习 python,它非常有趣,所以我希望尽可能变得更好!

编辑: 使用下面有关 asyncio 的信息,我现在得到 1.7-2.1 It/s,哪个更好!能不能更快一点?难道是我用错了?

import urllib.request
from tqdm import tqdm
import asyncio

with open("output.txt", "r") as file:
    itemIDS = [line.strip() for line in file]

async def download():
    x = 0
    for length in tqdm(itemIDS):
        await asyncio.sleep(1)
        urllib.request.urlretrieve(
            "https://imagemocksite.com?id="+str(itemIDS[x]), 
            "images/"+str(itemIDS[x])+".jpg")
        x += 1

asyncio.run(download())
print("All images downloaded")

最佳答案

评论已经提供了很好的建议,我认为您使用 asyncio 是正确的,它确实是完成此类工作的典型 Python 工具。

只是想提供一些帮助,因为您提供的代码并未真正发挥其功能。

首先您必须安装aiohttpaiofiles异步处理 HTTP 请求和本地文件系统 I/O。

然后,定义一个 download(item_id, session) 辅助协程,用于根据 item_id 下载单个图像。 session 将是 aiohttp.ClientSession,它是在 aiohttp 中运行异步 HTTP 请求的基类。

诀窍是最终拥有一个 download_all 协程,它可以同时在所有单独的 download() 协程上调用 asyncio.gatherasyncio.gather 是告诉 asyncio “并行”运行多个协程的方法。

这应该会大大加快您的下载速度。如果没有,那么就是第三方服务器限制了您。

import asyncio

import aiohttp
import aiofiles


with open("output.txt", "r") as file:
    itemIDS = [line.strip() for line in file]


async def download(item_id, session):
    url = "https://imagemocksite.com"
    filename = f"images/{item_id}.jpg"
    async with session.get(url, {"id": item_id}) as response:
        async with aiofiles.open(filename, "wb") as f:
            await f.write(await response.read())


async def download_all():
    async with aiohttp.ClientSession() as session:
        await asyncio.gather(
            *[download(item_id, session) for item_id in itemIDS]
        )


asyncio.run(download_all())
print("All images downloaded")

关于Python - 循环浏览大列表并快速下载图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67594624/

相关文章:

python - 合法的 python if 语句?

linux - 检测快速用户切换 Linux

c# - Add()性能:HashSet <T>,Dictionary <键,值>和列表<T>

javascript - 在 JavaScript 数组中更新现有变量

python - 如何从Python中的特定点开始Itertools循环?

python - 类型错误 : unbound method sprites()

python - 如何从日志的输出判断Tensorflow是否正在与GPU一起工作?

c++ - SIGALRM 超时——它如何影响现有操作?

c++ - 检查正确的输入会导致无限循环

python - Pandas DataFrame 在非唯一时间戳上切片数据