首頁 > 後端開發 > Python教學 > 怎麼使用Python進行多執行緒並發下載圖片

怎麼使用Python進行多執行緒並發下載圖片

青灯夜游
發布: 2022-10-26 19:14:17
轉載
3897 人瀏覽過

怎麼使用怎麼使用怎麼使用Python進行多執行緒並發下載圖片進行多執行緒並發下載圖片下載大量圖片?以下這篇文章為大家介紹一下使用怎麼使用怎麼使用Python進行多執行緒並發下載圖片進行多執行緒並發下載圖片進行多執行緒並發下載圖片的方法,希望對大家有幫助!

怎麼使用Python進行多執行緒並發下載圖片

有時候,下載大量圖像需要幾個小時——讓我們來解決這個問題

我明白了——你已經厭倦了等待你的程式下載圖像。有時我必須下載數千張圖像需要幾個小時,而且你不可能一直等待你的程式完成下載這些愚蠢的圖像。你有很多重要的事情要做。

讓我們建立一個簡單的圖像下載器腳本,它將讀取一個文字檔案並以超快的速度下載一個資料夾中列出的所有圖像。

最終效果

這就是我們最終要建立的效果。

image downloader python

怎麼使用怎麼使用Python進行多執行緒並發下載圖片進行多執行緒並發下載圖片

安裝依賴項

讓我們可以安裝每個人最喜歡的 requests 函式庫。

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
登入後複製

在這裡,我們重試下載圖片五次,以防失敗。現在,讓我們嘗試自動找到圖像的名稱並保存它。

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.b02_n.jpg?_nc_ht=instagram.fktm7–1.fna.ccdn.net&#ccat_nc_ht#cnc_cat_catc1.fna.ccdn.net ##?,然後只取它前面的任何東西。

這是我們最終的映像名稱:

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中文網其他相關文章!

相關標籤:
來源:learnku.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板