वेब से छवियों और अन्य फ़ाइलों को पायथन में डाउनलोड करें (व्यक्तिगत रूप से या बैचों में)

व्यापार

निम्नलिखित व्याख्या करता है कि पायथन में वेब पर किसी छवि, ज़िप, पीडीएफ, या अन्य फ़ाइल का URL कैसे निर्दिष्ट करें, इसे डाउनलोड करें और इसे स्थानीय फ़ाइल के रूप में सहेजें।

  • URL निर्दिष्ट करके चित्र डाउनलोड करें।
    • कोड उदाहरण
    • urllib.request.urlopen():यूआरएल खोलें
    • open():फ़ाइल को बाइनरी मोड में लिखें
    • एक सरल कोड उदाहरण
  • ज़िप फ़ाइलें, PDF फ़ाइलें आदि डाउनलोड करें।
  • वेब पेज पर छवि का 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)

यह यूआरएल से os.path.basename() के साथ फ़ाइल नाम निकालता है और गंतव्य पथ उत्पन्न करने के लिए इसे os.path.join() के साथ निर्दिष्ट निर्देशिका के साथ जोड़ता है।

निम्न अनुभाग डेटा प्राप्ति के भाग और फ़ाइल के रूप में डेटा बचत के भाग का वर्णन करते हैं।

urllib.request.urlopen():यूआरएल खोलें

URL खोलने और डेटा पुनर्प्राप्त करने के लिए urllib.request.urlopen() का उपयोग करें। ध्यान दें कि urllib.urlopen() को Python 2.6 और इससे पहले के संस्करण में पदावनत किया गया है। urllib.request.urlretrieve() अभी तक बहिष्कृत नहीं किया गया है, लेकिन भविष्य में हो सकता है।

अपवाद होने पर रुकने से बचने के लिए, कोशिश करें और छोड़कर त्रुटि को पकड़ें।

उदाहरण में, urllib.error आयात किया गया है और केवल urllib.error.URLError स्पष्ट रूप से कैप्चर किया गया है। फ़ाइल का URL मौजूद नहीं होने पर त्रुटि संदेश प्रदर्शित किया जाएगा।

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)

url खोलने और डेटा प्राप्त करने के लिए मानक लाइब्रेरी urllib के बजाय तृतीय-पक्ष लाइब्रेरी अनुरोधों का उपयोग करना भी संभव है।

खुले में बाइनरी मोड में फ़ाइल को लिखें ()

डेटा जो urllib.request.urlopen() से प्राप्त किया जा सकता है वह एक बाइट स्ट्रिंग (बाइट्स प्रकार) है।

ओपन () मोड = ‘डब्ल्यूबी’ के साथ दूसरा तर्क डेटा को बाइनरी के रूप में लिखता है। 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)

ज़िप फ़ाइलें, 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 स्वयं फ़ाइल का लिंक होना चाहिए।

उदाहरण के लिए, गिटहब रिपोजिटरी फ़ाइल के मामले में, निम्न यूआरएल में एक पीडीएफ एक्सटेंशन है लेकिन वास्तव में एक एचटीएमएल पेज है। यदि यह 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} का उपयोग 3 अंकों के बजाय 5 अंकों की संख्या के लिए किया जाता है। स्ट्रिंग str की स्वरूप विधि के बारे में अधिक जानकारी के लिए, निम्न आलेख देखें।

साथ ही, यहां हम आउटपुट को पढ़ने में आसान बनाने के लिए pprint का उपयोग कर रहे हैं।

सुंदर सूप के साथ निकालें

वेब पेजों से थोक में छवि URL निकालने के लिए, सुंदर सूप का उपयोग करें।

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

from bs4 import BeautifulSoup

url = 'https://hi.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 <img> के src तत्व या डेटा-src तत्व से प्राप्त करें; उपनाम।
    • img.get('data-src')

उपरोक्त नमूना कोड सिर्फ एक उदाहरण है और काम करने की गारंटी नहीं है।

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() का उपयोग करता हूं। इकाई सेकंड में है, इसलिए ऊपर के उदाहरण में, समय मॉड्यूल आयात और उपयोग किया जाता है।

उदाहरण छवि फ़ाइलों के लिए है, लेकिन अन्य प्रकार की फ़ाइलों को एक साथ डाउनलोड किया जा सकता है, जब तक कि वे सूचीबद्ध हैं।