पायथन 3 में वेब से फ़ाइल डाउनलोड करें


332

मैं एक प्रोग्राम बना रहा हूं जो एक वेब सर्वर से एक .jar (जावा) फ़ाइल डाउनलोड करेगा, जो उसी गेम / एप्लिकेशन की .adad फ़ाइल में निर्दिष्ट URL को पढ़कर होगा। मैं पायथन 3.2.1 का उपयोग कर रहा हूं

मैं JAD फ़ाइल से JAR फ़ाइल का URL निकालने में कामयाब रहा (हर JAD फ़ाइल में JAR फ़ाइल में URL शामिल है), लेकिन जैसा कि आप कल्पना कर सकते हैं, निकाला गया मान प्रकार () स्ट्रिंग है।

यहाँ प्रासंगिक समारोह है:

def downloadFile(URL=None):
    import httplib2
    h = httplib2.Http(".cache")
    resp, content = h.request(URL, "GET")
    return content

downloadFile(URL_from_file)

हालाँकि मुझे हमेशा यह कहते हुए एक त्रुटि मिलती है कि ऊपर के फ़ंक्शन का प्रकार बाइट्स होना है, न कि स्ट्रिंग। मैंने URL.encode ('utf-8'), और बाइट्स (URL, एन्कोडिंग = 'utf-8') का उपयोग करने की कोशिश की है, लेकिन मुझे हमेशा वही या समान त्रुटि मिलेगी।

तो मूल रूप से मेरा सवाल यह है कि URL को स्ट्रिंग प्रकार में संग्रहीत करने पर सर्वर से फ़ाइल कैसे डाउनलोड की जाए?


4
@ जलवास, इसके लिए एक इनाम? उत्तरदाता अभी भी (और काफी) एसओ पर सक्रिय है। क्यों न केवल एक टिप्पणी जोड़ें और पूछें?
भार्गव राव

8
कॉस एक अच्छा जवाब है जो समय की परीक्षा को समाप्त करता है, पुरस्कार देने के लायक है। साथ ही, हमें कई अन्य प्रश्नों के लिए यह करना शुरू करना चाहिए कि क्या उत्तर आज प्रासंगिक हैं या नहीं। विशेष रूप से तब जब SO उत्तरों की छंटाई पागल होती है, कभी-कभी आउट-डेटेड या सबसे खराब उत्तर शीर्ष पर जाता है।
अल्व्स

जवाबों:


646

यदि आप एक वेब पेज की सामग्री को एक चर में प्राप्त करना चाहते हैं, तो बस readकी प्रतिक्रिया urllib.request.urlopen:

import urllib.request
...
url = 'http://example.com/'
response = urllib.request.urlopen(url)
data = response.read()      # a `bytes` object
text = data.decode('utf-8') # a `str`; this step can't be used if data is binary

urllib.request.urlretrieveफ़ंक्शन का उपयोग करने के लिए फ़ाइल को डाउनलोड करने और सहेजने का सबसे आसान तरीका है :

import urllib.request
...
# Download the file from `url` and save it locally under `file_name`:
urllib.request.urlretrieve(url, file_name)
import urllib.request
...
# Download the file from `url`, save it in a temporary directory and get the
# path to it (e.g. '/tmp/tmpb48zma.txt') in the `file_name` variable:
file_name, headers = urllib.request.urlretrieve(url)

लेकिन ध्यान रखें कि विरासतurlretrieve माना जाता है और पदावनत हो सकता है (निश्चित नहीं कि क्यों, हालांकि)।

तो ऐसा करने का सबसे सही तरीका यह होगा कि आप urllib.request.urlopenफंक्शन का उपयोग करके किसी फाइल की तरह वस्तु का उपयोग करें जो एक HTTP प्रतिसाद का प्रतिनिधित्व करता है और एक वास्तविक फ़ाइल का उपयोग करके इसे कॉपी करता है shutil.copyfileobj

import urllib.request
import shutil
...
# Download the file from `url` and save it locally under `file_name`:
with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
    shutil.copyfileobj(response, out_file)

यदि यह बहुत जटिल लगता है, तो आप सरल होकर किसी bytesऑब्जेक्ट में पूरे डाउनलोड को स्टोर कर सकते हैं और फिर इसे एक फाइल पर लिख सकते हैं। लेकिन यह केवल छोटी फाइलों के लिए अच्छा काम करता है।

import urllib.request
...
# Download the file from `url` and save it locally under `file_name`:
with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
    data = response.read() # a `bytes` object
    out_file.write(data)

.gzमक्खी पर संपीड़ित (और शायद अन्य प्रारूप) डेटा को संपीड़ित करना संभव है , लेकिन इस तरह के एक ऑपरेशन को संभवतः फ़ाइल के लिए यादृच्छिक पहुँच का समर्थन करने के लिए HTTP सर्वर की आवश्यकता होती है।

import urllib.request
import gzip
...
# Read the first 64 bytes of the file inside the .gz archive located at `url`
url = 'http://example.com/something.gz'
with urllib.request.urlopen(url) as response:
    with gzip.GzipFile(fileobj=response) as uncompressed:
        file_header = uncompressed.read(64) # a `bytes` object
        # Or do anything shown above using `uncompressed` instead of `response`.

7
आप हेडर से कैरेक्टर एन्कोडिंग प्राप्त करने के लिए response.info().get_param('charset', 'utf-8')utf-8Content-Type
हार्डकॉकिंग के

2
@OlehPrypin outfile.write(data)केवल छोटी फ़ाइलों के लिए ही अच्छा काम क्यों करता है ?
स्टार्टेक

"urlretrieve विरासत माना जाता है और पदावनत हो सकता है" आपको यह विचार कहां से मिला?
कोरी गोल्डबर्ग

13
@ कोरी: डॉक्स से सही : "21.6.24। लिगेसी इंटरफ़ेस निम्नलिखित कार्य और कक्षाएं पायथन 2 मॉड्यूल urllib (urllib2 के विपरीत) से पोर्ट किए गए हैं। वे भविष्य में किसी बिंदु पर पदावनत हो सकते हैं।" ... और मैं ओलेह के "क्यों नहीं यकीन है" पर सहमत हूँ
सीएफ

@ ओले Prypin अगर मैं urllib.request.urlopen (url) के साथ प्रतिक्रिया के रूप में उपयोग करता हूं, तो out_file के रूप में खोलें (file_name, 'wb'): shutil.copyfileobj (प्रतिक्रिया, out_file) तो मैं कैच स्टेटमेंट में HTTP स्टेटस कोड कैसे खोज सकता हूं फ़ाइल नहीं मिली?
रॉबर्ट अचमन

145

requestsजब भी मुझे HTTP अनुरोधों से संबंधित कुछ चाहिए, तो मैं पैकेज का उपयोग करता हूं क्योंकि इसका एपीआई शुरू करना बहुत आसान है:

सबसे पहले, स्थापित करें requests

$ pip install requests

फिर कोड:

from requests import get  # to make GET request


def download(url, file_name):
    # open in binary mode
    with open(file_name, "wb") as file:
        # get request
        response = get(url)
        # write to file
        file.write(response.content)

16

मुझे आशा है कि मैंने प्रश्न को सही समझा, जो है: जब सर्वर को स्ट्रिंग प्रकार में संग्रहीत किया जाता है, तो सर्वर से फ़ाइल कैसे डाउनलोड करें?

मैं फ़ाइलें डाउनलोड करता हूं और स्थानीय रूप से नीचे दिए गए कोड का उपयोग करके इसे बचाता हूं:

import requests

url = 'https://www.python.org/static/img/python-logo.png'
fileName = 'D:\Python\dwnldPythonLogo.png'
req = requests.get(url)
file = open(fileName, 'wb')
for chunk in req.iter_content(100000):
    file.write(chunk)
file.close()

नमस्ते, मैं भी फ़ाइल डाउनलोड करने के लिए एक ही प्रकार के कोड का उपयोग कर रहा हूं, लेकिन कुछ समय के लिए मुझे अपवाद का सामना करना पड़ रहा है जैसे - 'चार्मैप' कोडक चरित्र को एन्कोड नहीं कर सकता '\ u010c' ..... क्या आप मेरी मदद कर सकते हैं
जॉयसन

10

यहां हम Python3 में urllib के लिगेसी इंटरफेस का उपयोग कर सकते हैं:

निम्नलिखित कार्यों और कक्षाओं को पायथन 2 मॉड्यूल urllib (urllib2 के विपरीत) से पोर्ट किया गया है। वे भविष्य में किसी बिंदु पर पदावनत हो सकते हैं।

उदाहरण (2 लाइन कोड) :

import urllib.request

url = 'https://www.python.org/static/img/python-logo.png'
urllib.request.urlretrieve(url, "logo.png")

9

आप wget का उपयोग कर सकते हैं जो कि इसके लिए लोकप्रिय डाउनलोडिंग शेल टूल है। https://pypi.python.org/pypi/wget इस सरल विधि के बाद से यह गंतव्य फ़ाइल को खोलने के लिए की जरूरत नहीं है हो जाएगा। यहाँ एक उदाहरण है।

import wget
url = 'https://i1.wp.com/python3.codes/wp-content/uploads/2015/06/Python3-powered.png?fit=650%2C350'  
wget.download(url, '/Users/scott/Downloads/cat4.jpg') 

0

हाँ, निश्चित रूप से अनुरोध HTTP अनुरोध से संबंधित किसी चीज़ में उपयोग करने के लिए बढ़िया पैकेज है। लेकिन हमें आने वाले डेटा के एन्कोडिंग प्रकार के साथ सावधान रहने की आवश्यकता है और साथ ही नीचे एक उदाहरण है जो अंतर बताता है


from requests import get

# case when the response is byte array
url = 'some_image_url'

response = get(url)
with open('output', 'wb') as file:
    file.write(response.content)


# case when the response is text
# Here unlikely if the reponse content is of type **iso-8859-1** we will have to override the response encoding
url = 'some_page_url'

response = get(url)
# override encoding by real educated guess as provided by chardet
r.encoding = r.apparent_encoding

with open('output', 'w', encoding='utf-8') as file:
    file.write(response.content)


0

प्रेरणा

कभी-कभी, हम चित्र प्राप्त करना चाहते हैं, लेकिन इसे वास्तविक फ़ाइलों में डाउनलोड करने की आवश्यकता नहीं है,

यानी, डेटा डाउनलोड करें और मेमोरी पर रखें।

उदाहरण के लिए, यदि मैं मशीन सीखने की विधि का उपयोग करता हूं, तो एक मॉडल को प्रशिक्षित करें जो संख्या (बार कोड) के साथ एक छवि को पहचान सकता है।

जब मैं कुछ वेबसाइटों पर जासूसी करता हूं और उनमें वे छवियां होती हैं तो मैं इसे पहचानने के लिए मॉडल का उपयोग कर सकता हूं,

और मैं अपनी डिस्क ड्राइव पर उन चित्रों को सहेजना नहीं चाहता,

फिर आप नीचे दिए गए तरीके को आजमा सकते हैं, ताकि आप मेमोरी पर डेटा डाउनलोड कर सकें।

अंक

import requests
from io import BytesIO
response = requests.get(url)
with BytesIO as io_obj:
    for chunk in response.iter_content(chunk_size=4096):
        io_obj.write(chunk)

मूल रूप से, @ रणविजय कुमार को पसंद है

एक उदाहरण

import requests
from typing import NewType, TypeVar
from io import StringIO, BytesIO
import matplotlib.pyplot as plt
import imageio

URL = NewType('URL', str)
T_IO = TypeVar('T_IO', StringIO, BytesIO)


def download_and_keep_on_memory(url: URL, headers=None, timeout=None, **option) -> T_IO:
    chunk_size = option.get('chunk_size', 4096)  # default 4KB
    max_size = 1024 ** 2 * option.get('max_size', -1)  # MB, default will ignore.
    response = requests.get(url, headers=headers, timeout=timeout)
    if response.status_code != 200:
        raise requests.ConnectionError(f'{response.status_code}')

    instance_io = StringIO if isinstance(next(response.iter_content(chunk_size=1)), str) else BytesIO
    io_obj = instance_io()
    cur_size = 0
    for chunk in response.iter_content(chunk_size=chunk_size):
        cur_size += chunk_size
        if 0 < max_size < cur_size:
            break
        io_obj.write(chunk)
    io_obj.seek(0)
    """ save it to real file.
    with open('temp.png', mode='wb') as out_f:
        out_f.write(io_obj.read())
    """
    return io_obj


def main():
    headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7',
        'Cache-Control': 'max-age=0',
        'Connection': 'keep-alive',
        'Host': 'statics.591.com.tw',
        'Upgrade-Insecure-Requests': '1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36'
    }
    io_img = download_and_keep_on_memory(URL('http://statics.591.com.tw/tools/showPhone.php?info_data=rLsGZe4U%2FbphHOimi2PT%2FhxTPqI&type=rLEFMu4XrrpgEw'),
                                         headers,  # You may need this. Otherwise, some websites will send the 404 error to you.
                                         max_size=4)  # max loading < 4MB
    with io_img:
        plt.rc('axes.spines', top=False, bottom=False, left=False, right=False)
        plt.rc(('xtick', 'ytick'), color=(1, 1, 1, 0))  # same of plt.axis('off')
        plt.imshow(imageio.imread(io_img, as_gray=False, pilmode="RGB"))
        plt.show()


if __name__ == '__main__':
    main()


-3
from urllib import request

def get(url):
    with request.urlopen(url) as r:
        return r.read()


def download(url, file=None):
    if not file:
        file = url.split('/')[-1]
    with open(file, 'wb') as f:
        f.write(get(url))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.