دانلود تصاویر و فایل های دیگر از وب در پایتون (به صورت جداگانه یا دسته ای)

کسب و کار

در ادامه نحوه تعیین URL یک تصویر، ZIP، PDF یا فایل های دیگر در وب در پایتون، دانلود و ذخیره آن به عنوان یک فایل محلی توضیح داده شده است.

  • با مشخص کردن URL تصاویر را دانلود کنید.
    • نمونه کد
    • urllib.request.urlopen():URL را باز کنید
    • open():در یک فایل در حالت باینری بنویسید
    • یک مثال کد ساده تر
  • دانلود فایل های ZIP، فایل های PDF و غیره
  • URL تصویر را در صفحه وب استخراج کنید.
    • اگر عدد به ترتیب باشد
    • با سوپ زیبا عصاره بگیرید
  • دانلود دسته ای چندین تصویر از لیست URL ها

با مشخص کردن URL تصاویر را دانلود کنید.

شما می توانید از کتابخانه استاندارد فقط برای دانلود فایل های فردی با مشخص کردن URL های آنها استفاده کنید. نصب اضافی مورد نیاز نیست

نمونه کد

در زیر نمونه ای از تابعی است که با تعیین آدرس URL و مسیر مقصد و نحوه استفاده از آن یک فایل را دانلود و ذخیره می کند. این کد برای توضیح کمی پیچیده است. یک مثال ساده در زیر آورده شده است.

import os
import pprint
import time
import urllib.error
import urllib.request

def download_file(url, dst_path):
    try:
        with urllib.request.urlopen(url) as web_file:
            data = web_file.read()
            with open(dst_path, mode='wb') as local_file:
                local_file.write(data)
    except urllib.error.URLError as e:
        print(e)
url = 'https://www.python.org/static/img/python-logo.png'
dst_path = 'data/temp/py-logo.png'
download_file(url, dst_path)

برای تعیین دایرکتوری مقصد و ذخیره فایل با نام فایل URL، موارد زیر را انجام دهید

def download_file_to_dir(url, dst_dir):
    download_file(url, os.path.join(dst_dir, os.path.basename(url)))

dst_dir = 'data/temp'
download_file_to_dir(url, dst_dir)

نام فایل را از URL با os.path.basename() استخراج می کند و آن را با دایرکتوری مشخص شده با os.path.join() می پیوندد تا مسیر مقصد را ایجاد کند.

بخش‌های زیر بخشی از جمع‌آوری داده و بخشی از ذخیره داده‌ها را به عنوان یک فایل توضیح می‌دهند.

urllib.request.urlopen():URL را باز کنید

از urllib.request.urlopen() برای باز کردن URL و بازیابی داده ها استفاده کنید. توجه داشته باشید که ()urllib.urlopen در پایتون 2.6 و قبل از آن منسوخ شده است. urllib.request.urlretrieve() هنوز منسوخ نشده است، اما ممکن است در آینده باشد.

برای جلوگیری از توقف زمانی که یک استثنا رخ می دهد، خطا را با try و استثنا بگیرید.

در مثال، urllib.error وارد شده است و فقط urllib.error.URLError به صراحت ثبت شده است. زمانی که آدرس فایل موجود نباشد پیام خطا نمایش داده می شود.

url_error = 'https://www.python.org/static/img/python-logo_xxx.png'
download_file_to_dir(url_error, dst_dir)
# HTTP Error 404: Not Found

اگر می‌خواهید هنگام ذخیره محلی، استثناها (FileNotFoundError و غیره) را نیز بگیرید، موارد زیر را انجام دهید.
(urllib.error.URLError, FileNotFoundError)

همچنین می توان از Requests های کتابخانه شخص ثالث به جای urllib استاندارد کتابخانه برای باز کردن url و دریافت داده ها استفاده کرد.

نوشتن در یک فایل در حالت باینری در open()

داده ای که می توان با urllib.request.urlopen() بدست آورد یک رشته بایت (نوع بایت) است.

Open() با mode=’wb’ به عنوان آرگومان دوم، داده ها را به صورت باینری می نویسد. w به معنای نوشتن و b به معنای باینری است.

یک مثال کد ساده تر

عبارات تودرتو با کاما را می توان به یکباره نوشت.

با استفاده از این می توانیم موارد زیر را بنویسیم.

def download_file(url, dst_path):
    try:
        with urllib.request.urlopen(url) as web_file, open(dst_path, 'wb') as local_file:
            local_file.write(web_file.read())
    except urllib.error.URLError as e:
        print(e)

دانلود فایل های ZIP، فایل های PDF و غیره

مثال‌هایی که تا به اینجا ارائه شده برای دانلود و ذخیره فایل‌های تصویری است، اما از آنجایی که ما به سادگی یک فایل را در وب باز می‌کنیم و آن را به عنوان یک فایل محلی ذخیره می‌کنیم، می‌توان از همان عملکردها برای انواع دیگر فایل‌ها استفاده کرد.

با مشخص کردن URL می توانید فایل ها را دانلود و ذخیره کنید.

url_zip = 'https://from-locas.com/sample_header.csv.zip'
download_file_to_dir(url_zip, dst_dir)

url_xlsx = 'https://from-locas/sample.xlsx'
download_file_to_dir(url_xlsx, dst_dir)

url_pdf = 'https://from-locas/sample1.pdf'
download_file_to_dir(url_pdf, dst_dir)

توجه داشته باشید که URL مشخص شده در این تابع باید پیوندی به خود فایل باشد.

به عنوان مثال، در مورد یک فایل مخزن GitHub، آدرس زیر دارای پسوند pdf است اما در واقع یک صفحه html است. اگر این URL در تابع بالا مشخص شده باشد، منبع html دانلود خواهد شد.

  • https://github.com/from-locals/python-snippets/blob/master/notebook/data/src/pdf/sample1.pdf

لینک موجودیت فایل URL زیر است که اگر می خواهید فایل را دانلود و ذخیره کنید باید آن را مشخص کنید.

  • https://github.com/from-locals/python-snippets/raw/master/notebook/data/src/pdf/sample1.pdf

همچنین مواردی وجود دارد که دسترسی توسط عامل کاربر، ارجاع دهنده و غیره محدود می شود و دانلود را غیرممکن می کند. ما تضمین نمی کنیم که همه فایل ها دانلود شوند.

استفاده از درخواست‌ها برای تغییر یا افزودن سرصفحه‌های درخواست مانند عامل کاربر آسان است.

URL تصویر را در صفحه وب استخراج کنید.

برای دانلود همزمان تمامی تصاویر در یک صفحه، ابتدا آدرس تصاویر را استخراج کرده و یک لیست ایجاد کنید.

اگر عدد به ترتیب باشد

اگر URL تصویری که می خواهید دانلود کنید یک عدد ترتیبی ساده باشد، آسان است. اگر URL ها نه تنها اعداد متوالی هستند، بلکه دارای نظم و ترتیبی نیز هستند، به جای خراشیدن با سوپ زیبا، ساده تر است که فهرستی از URL ها را مطابق با قوانین تهیه کنید (به زیر مراجعه کنید).

از نماد درک لیست استفاده کنید.

url_list = ['https://example.com/basedir/base_{:03}.jpg'.format(i) for i in range(5)]
pprint.pprint(url_list)
# ['https://example.com/basedir/base_000.jpg',
#  'https://example.com/basedir/base_001.jpg',
#  'https://example.com/basedir/base_002.jpg',
#  'https://example.com/basedir/base_003.jpg',
#  'https://example.com/basedir/base_004.jpg']

در مثال بالا، {:03} برای یک عدد ترتیبی 3 رقمی با صفر استفاده می شود. از {} ​​زمانی استفاده می‌شود که پر کردن صفر ضروری نباشد، و {:05} برای یک عدد 5 رقمی به جای 3 رقم استفاده می‌شود. برای اطلاعات بیشتر در مورد روش قالب بندی string str به مقاله زیر مراجعه کنید.

همچنین، در اینجا ما از pprint استفاده می کنیم تا خروجی را راحت تر بخوانیم.

با سوپ زیبا عصاره بگیرید

برای استخراج URL های تصویر از صفحات وب به صورت انبوه، از Beautiful Soup استفاده کنید.

import os
import time
import urllib.error
import urllib.request

from bs4 import BeautifulSoup

url = 'https://fa.from-locals.com/'
ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) '\
     'AppleWebKit/537.36 (KHTML, like Gecko) '\
     'Chrome/55.0.2883.95 Safari/537.36 '

req = urllib.request.Request(url, headers={'User-Agent': ua})
html = urllib.request.urlopen(req)

soup = BeautifulSoup(html, "html.parser")

url_list = [img.get('data-src') for img in soup.find(class_='list').find_all('img')]

در مثال، URL تصویر کوچک این وب سایت استخراج شده است.

ساختار بسته به صفحه وب متفاوت است، اما اساساً به صورت زیر بدست می آید.

  • دریافت لیستی از <img> با تعیین کلاس، شناسه و غیره بلوک حاوی چندین تصویری که می خواهید دانلود کنید، اشیاء را تگ کنید.
    • soup.find(class_='list').find_all('img')
  • URL تصویر را از عنصر src یا عنصر data-src از <img> برچسب زدن
    • img.get('data-src')

کد نمونه بالا فقط یک نمونه است و تضمینی برای کارکرد ندارد.

دانلود دسته ای چندین تصویر از لیست URL ها

اگر فهرستی از URL ها دارید، می توانید آن را در یک حلقه for تبدیل کنید و تابع را فراخوانی کنید تا فایل را با اولین URL نشان داده شده دانلود و ذخیره کنید. به دلیل لیست موقت URL، فراخوانی تابع download_image_dir() در اینجا توضیح داده شده است.

download_dir = 'data/temp'
sleep_time_sec = 1

for url in url_list:
    print(url)
#     download_file_dir(url, download_dir)
    time.sleep(sleep_time_sec)
# https://example.com/basedir/base_000.jpg
# https://example.com/basedir/base_001.jpg
# https://example.com/basedir/base_002.jpg
# https://example.com/basedir/base_003.jpg
# https://example.com/basedir/base_004.jpg

برای اینکه سرور بیش از حد بارگیری نشود، از time.sleep() برای ایجاد زمان انتظار برای هر بار دانلود تصویر استفاده می کنم. واحد بر حسب ثانیه است، بنابراین در مثال بالا، ماژول زمان وارد و استفاده می شود.

مثال برای فایل‌های تصویری است، اما انواع دیگر فایل‌ها را می‌توان با هم دانلود کرد، البته تا زمانی که فهرست شده باشند.

Copied title and URL