有時候,下載大量圖像需要幾個小時——讓我們來解決這個問題
我明白了——你已經厭倦了等待你的程式下載圖像。有時我必須下載數千張圖像需要幾個小時,而且你不可能一直等待你的程式完成下載這些愚蠢的圖像。你有很多重要的事情要做。
讓我們建立一個簡單的圖像下載器腳本,它將讀取一個文字檔案並以超快的速度下載一個資料夾中列出的所有圖像。
這就是我們最終要建立的效果。
讓我們可以安裝每個人最喜歡的 requests 函式庫。
pip install requests
現在,我們將看到一些用於下載單一 URL 並嘗試自動尋找圖像名稱以及如何使用重試的基本程式碼。
import requests res = requests.get(img_url, stream=True) count = 1 while res.status_code != 200 and count <p>在這裡,我們重試下載圖片五次,以防失敗。現在,讓我們嘗試自動找到圖像的名稱並保存它。 </p><pre class="brush:php;toolbar:false">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('/')) + 1:]) if '?' in image_name: image_name = image_name[:image_name.find('?')]
假設我們要下載的URL 是:
instagram.fktm7-1.fna.fbcdn.net/vp ....
好吧,這是一團糟。讓我們分解一下程式碼對 URL 的作用。我們首先使用 rfind
找到最後一個正斜線(/
),然後選擇之後的所有內容。這是結果:
65872070_1200425330158967_6201268309743367902_n.jpg?_nc_ht=instagram.fktm7–1.fna.ccdn.net&_fb_nc_ht#cnc_cat_catc1#.fna.ccdn.net&_fb_cat_1111 月的第二個部分找到我們的第二個部分。 ##?,然後只取它前面的任何東西。
這是我們最終的映像名稱:
這個結果非常好,適用於大多數用例。 現在我們已經下載了圖片名稱和映像,我們將保存它。
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'Downloading: {img_url}') res = requests.get(img_url, stream=True) count = 1 while res.status_code != 200 and count <p>現在,你可能會問:「這個人所說的多處理在哪裡?」。 </p><p>這很簡單。我們將簡單地定義我們的池並將我們的函數和圖像 URL 傳遞給它。 </p><pre class="brush:php;toolbar:false">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'MESSAGE: Running {process} process') 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('ERROR: Please provide the txt file\n$python image_downloader.py cats.txt') name = url_input.split('.')[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('ERROR: Please provide the txt file\n Example \n\n$python image_downloader.py dogs.txt \n\n') sys.exit() with open(url_input, 'r') as f: images_url = f.read().splitlines() print('{} Images detected'.format(len(images_url))) return images_url def image_downloader(img_url: str): """ 输入选项: 参数: img_url str (Image url) 尝试下载图像 url 并使用标题中提供的名称。否则它会随机选择一个名字 """ print(f'Downloading: {img_url}') res = requests.get(img_url, stream=True) count = 1 while res.status_code != 200 and count <h2>將其儲存到Python怎麼多線程並發下載圖片怎麼多線程並發下載圖片 檔案中,然後執行它。 <strong><pre class="brush:php;toolbar:false">python3 image_downloader.py cats.txt這是 GitHub 儲存庫的連結。 用法
python3 image_downloader.py <filename_with_urls_seperated_by_newline.txt> <num_of_process></num_of_process></filename_with_urls_seperated_by_newline.txt>
是可選的(預設情況下,它使用 10 個進程)。
範例
python3 image_downloader.py cats.txt
#【相關推薦:#Python怎麼多線程並發下載圖片怎麼多線程並發下載圖片3影片教學
】
以上是Python怎麼多線程並發下載圖片的詳細內容。更多資訊請關注PHP中文網其他相關文章!