ホームページ  >  記事  >  バックエンド開発  >  Python を使用して複数のスレッドで同時に画像をダウンロードする方法

Python を使用して複数のスレッドで同時に画像をダウンロードする方法

青灯夜游
青灯夜游転載
2022-10-26 19:14:173808ブラウズ

Python を使用して複数のスレッドで同時に画像をダウンロードする方法 を使用して複数のスレッドで同時に画像をダウンロードする方法 を使用して大量の画像をダウンロードするにはどうすればよいですか?以下の記事では、Python を使用して複数のスレッドで同時に画像をダウンロードする方法 を使用して複数のスレッドで同時に画像をダウンロードする方法を使って複数のスレッドで画像を同時ダウンロードする方法を紹介しますので、ご参考になれば幸いです。

Python を使用して複数のスレッドで同時に画像をダウンロードする方法

大量の画像をダウンロードするのに数時間かかる場合があります - それを修正しましょう

わかりました - 画像をダウンロードするプログラムを待つのはうんざりです。時々、何時間もかかる何千枚もの画像をダウンロードしなければならないことがありますが、プログラムがこれらのばかげた画像のダウンロードを完了するのを待ち続けることはできません。やるべき重要なことがたくさんあります。

テキスト ファイルを読み取り、フォルダー内にリストされているすべての画像を超高速でダウンロードする、単純な画像ダウンローダー スクリプトを構築しましょう。

最終エフェクト

これが、構築する最後のエフェクトです。

image downloader python

Python を使用して複数のスレッドで同時に画像をダウンロードする方法 を使用して複数のスレッドで同時に画像をダウンロードする方法

#依存関係のインストール

みんなのお気に入りのリクエスト ライブラリをインストールしましょう。

pip install requests

次に、単一の URL をダウンロードし、イメージ名を自動的に検索するための基本的なコードと、再試行の使用方法を見ていきます。

import requests

res = requests.get(img_url, stream=True)
count = 1
while res.status_code != 200 and count <= 5:
    res = requests.get(img_url, stream=True)
    print(f&#39;Retry: {count} {img_url}&#39;)
    count += 1

ここでは、失敗した場合に備えて、イメージのダウンロードを 5 回再試行します。ここで、画像の名前を自動的に検索して保存してみましょう。

import more required library

import io
from PIL import Image

# lets try to find the image name
image_name = str(img_url[(img_url.rfind(&#39;/&#39;)) + 1:])
if &#39;?&#39; in image_name:
    image_name = image_name[:image_name.find(&#39;?&#39;)]

説明

ダウンロードしたい URL が

instagram.fktm7-1.fna.fbcdn であるとします。 .net/vp...

わかりました、これは混乱です。コードが URL に対して何を行うのかを詳しく見てみましょう。まず

rfind を使用して最後のスラッシュ (/) を検索し、それ以降のすべてを選択します。結果は次のとおりです:

##65872070_1200425330158967_6201268309743367902_n.jpg?_nc_ht=instagram.fktm7–1.fna.fbcdn.net&_nc_cat=111

次は 2 番目の部分で、

を見つけます。 ?

そして、その前にあるものをそのまま取ります。 これは最終的なイメージ名です:

65872070_1200425330158967_6201268309743367902_n.jpg

この結果は非常に良好で、ほとんどのユースケースに適しています。

イメージ名とイメージをダウンロードしたので、保存します。

i = Image.open(io.BytesIO(res.content))
i.save(image_name)

「上記のコードは一体どうやって使えばいいの?」と思っているなら、その通りです。これは美しい関数であり、上で行ったことはすべてフラット化されています。ここでは、イメージ名が見つからない場合に備えて、ダウンロードされたタイプがイメージであるかどうかもテストします。

def image_downloader(img_url: str):
    """
    Input:
    param: img_url  str (Image url)
    Tries to download the image url and use name provided in headers. Else it randomly picks a name
    """
    print(f&#39;Downloading: {img_url}&#39;)
    res = requests.get(img_url, stream=True)
    count = 1
    while res.status_code != 200 and count <= 5:
        res = requests.get(img_url, stream=True)
        print(f&#39;Retry: {count} {img_url}&#39;)
        count += 1
    # checking the type for image
    if &#39;image&#39; not in res.headers.get("content-type", &#39;&#39;):
        print(&#39;ERROR: URL doesnot appear to be an image&#39;)
        return False
    # Trying to red image name from response headers
    try:
        image_name = str(img_url[(img_url.rfind(&#39;/&#39;)) + 1:])
        if &#39;?&#39; in image_name:
            image_name = image_name[:image_name.find(&#39;?&#39;)]
    except:
        image_name = str(random.randint(11111, 99999))+&#39;.jpg&#39;

    i = Image.open(io.BytesIO(res.content))
    download_location = &#39;cats&#39;
    i.save(download_location + &#39;/&#39;+image_name)
    return f&#39;Download complete: {img_url}&#39;

ここで、「この人が話しているマルチプロセッシングとは何ですか?」と疑問に思うかもしれません。

これはとても簡単です。プールを定義し、それに関数と画像の URL を渡すだけです。

results = ThreadPool(process).imap_unordered(image_downloader, images_url)
for r in results:
    print(r)

これを関数に入れてみましょう:

def run_downloader(process:int, images_url:list):
    """
    Inputs:
        process: (int) number of process to run
        images_url:(list) list of images url
    """
    print(f&#39;MESSAGE: Running {process} process&#39;)
    results = ThreadPool(process).imap_unordered(image_downloader, images_url)
    for r in results:
        print(r)

繰り返しになりますが、「これは十分に良いことですが、すぐに 1000 枚の画像リストのダウンロードを開始したいと思います。このコードをすべてコピーして貼り付けて、すべてをマージする方法を考え出す必要はありません。」

これは完全なスクリプトです。次の処理を実行します。

    イメージ リスト テキスト ファイルとプロセス番号を入力として受け取ります
  • 必要な速度でそれらをダウンロードします
  • ファイルのダウンロードにかかる合計時間を出力します
  • ファイル名を読み取り、エラーやその他の処理に役立つ便利な関数もいくつかあります。
完全なスクリプト

# -*- coding: utf-8 -*-
import io
import random
import shutil
import sys
from multiprocessing.pool import ThreadPool
import pathlib

import requests
from PIL import Image
import time

start = time.time()

def get_download_location():
    try:
        url_input = sys.argv[1]
    except IndexError:
        print(&#39;ERROR: Please provide the txt file\n$python image_downloader.py cats.txt&#39;)
    name = url_input.split(&#39;.&#39;)[0]
    pathlib.Path(name).mkdir(parents=True, exist_ok=True)
    return name

def get_urls():
    """
    通过读取终端中作为参数提供的 txt 文件返回 url 列表
    """
    try:
        url_input = sys.argv[1]
    except IndexError:
        print(&#39;ERROR: Please provide the txt file\n Example \n\n$python image_downloader.py dogs.txt \n\n&#39;)
        sys.exit()
    with open(url_input, &#39;r&#39;) as f:
        images_url = f.read().splitlines()

    print(&#39;{} Images detected&#39;.format(len(images_url)))
    return images_url

def image_downloader(img_url: str):
    """
    输入选项:
    参数: img_url  str (Image url)
    尝试下载图像 url 并使用标题中提供的名称。否则它会随机选择一个名字
    """
    print(f&#39;Downloading: {img_url}&#39;)
    res = requests.get(img_url, stream=True)
    count = 1
    while res.status_code != 200 and count <= 5:
        res = requests.get(img_url, stream=True)
        print(f&#39;Retry: {count} {img_url}&#39;)
        count += 1
    # checking the type for image
    if &#39;image&#39; not in res.headers.get("content-type", &#39;&#39;):
        print(&#39;ERROR: URL doesnot appear to be an image&#39;)
        return False
    # Trying to red image name from response headers
    try:
        image_name = str(img_url[(img_url.rfind(&#39;/&#39;)) + 1:])
        if &#39;?&#39; in image_name:
            image_name = image_name[:image_name.find(&#39;?&#39;)]
    except:
        image_name = str(random.randint(11111, 99999))+&#39;.jpg&#39;

    i = Image.open(io.BytesIO(res.content))
    download_location = get_download_location()
    i.save(download_location + &#39;/&#39;+image_name)
    return f&#39;Download complete: {img_url}&#39;

def run_downloader(process:int, images_url:list):
    """
    输入项:
        process: (int) number of process to run
        images_url:(list) list of images url
    """
    print(f&#39;MESSAGE: Running {process} process&#39;)
    results = ThreadPool(process).imap_unordered(image_downloader, images_url)
    for r in results:
        print(r)

try:
    num_process = int(sys.argv[2])
except:
    num_process = 10

images_url = get_urls()
run_downloader(num_process, images_url)

end = time.time()
print(&#39;Time taken to download {}&#39;.format(len(get_urls())))
print(end - start)
これを Python を使用して複数のスレッドで同時に画像をダウンロードする方法 を使用して複数のスレッドで同時に画像をダウンロードする方法 ファイルに保存して実行します。

python3 image_downloader.py cats.txt

これは

GitHub リポジトリ

へのリンクです。

使用方法

python3 image_downloader.py <filename_with_urls_seperated_by_newline.txt> <num_of_process>
これにより、テキスト ファイル内のすべての URL が読み取られ、ファイル名と同じ名前のフォルダーにダウンロードされます。

num_of_process

はオプションです (デフォルトでは 10 プロセスが使用されます)。

#例

python3 image_downloader.py cats.txt

image downloader python

喜んでアドバイスさせていただきますこれをさらに進める方法について これを改善するための対応。 Python を使用して複数のスレッドで同時に画像をダウンロードする方法 を使用して複数のスレッドで同時に画像をダウンロードする方法

【関連する推奨事項:

Python を使用して複数のスレッドで同時に画像をダウンロードする方法 を使用して複数のスレッドで同時に画像をダウンロードする方法3 ビデオ チュートリアル

]

以上がPython を使用して複数のスレッドで同時に画像をダウンロードする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。