পাইথন 3 তে ওয়েব থেকে ফাইল ডাউনলোড করুন


332

আমি একটি প্রোগ্রাম তৈরি করছি যা একই সার্ভার / অ্যাপ্লিকেশনের .jad ফাইলটিতে উল্লিখিত URL টি পড়ে একটি ওয়েব সার্ভার থেকে একটি .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') ব্যবহার করার চেষ্টা করেছি, তবে আমি সর্বদা একই বা অনুরূপ ত্রুটি পেয়েছি।

সুতরাং মূলত আমার প্রশ্নটি হল যখন ইউআরএল স্ট্রিং টাইপের মধ্যে সংরক্ষণ করা হয় তখন সার্ভার থেকে কোনও ফাইল ডাউনলোড করবেন?


4
@ আলওয়াস, এর জন্য একটি অনুগ্রহ? উত্তরদাতা এখনও (এবং যথেষ্ট) এসওতে সক্রিয়। কেন শুধু একটি মন্তব্য যুক্ত করে জিজ্ঞাসা করবেন না?
ভার্গব রাও

8
সময় পরীক্ষা স্থায়ী যে একটি ভাল উত্তর পুরষ্কার মূল্যবান। এছাড়াও, উত্তরগুলি আজ প্রাসঙ্গিক কিনা তা পরীক্ষা করার জন্য আমাদের প্রচুর অন্যান্য প্রশ্নের জন্য এটি করা শুরু করা উচিত। বিশেষত যখন এসও উত্তরগুলি বাছাই করা বরং পাগল হয়, কখনও কখনও সেকেলে বা এমনকি সবচেয়ে খারাপ উত্তরও শীর্ষে যায়।
আলভাস

উত্তর:


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হ'ল এইচটিটিপি প্রতিক্রিয়া উপস্থাপন করে এমন একটি ফাইল-জাতীয় অবজেক্ট ফিরিয়ে ফাংশনটি ব্যবহার করা এবং এটি ব্যবহার করে একটি আসল ফাইলে অনুলিপি করা 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সংকুচিত ডেটা বের করা (এবং সম্ভবত অন্যান্য ফর্ম্যাটগুলি) পাওয়া সম্ভব , তবে এই জাতীয় অপারেশনের জন্য সম্ভবত এইচটিটিপি সার্ভারের ফাইলটিতে এলোমেলো অ্যাক্সেস সমর্থন করা প্রয়োজন।

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
jfs

2
@ ওলেহপ্রাইপিন কেন outfile.write(data)কেবল ছোট ফাইলগুলির জন্য ভাল কাজ করে?
স্টারটেক

"urlretrieve উত্তরাধিকার হিসাবে বিবেচিত হয় এবং অবহেলিত হতে পারে" আপনি এই ধারণাটি কোথায় পেয়েছেন?
কোরি গোল্ডবার্গ

13
@ কোরি: ডক্স থেকে সরাসরি : "21.6.24। লিগ্যাসি ইন্টারফেস নীচের ফাংশন এবং ক্লাসগুলি পাইথন 2 মডিউল urllib (urllib2 এর বিপরীতে) থেকে পোর্ট করা হয়েছে They ভবিষ্যতে তারা কোনও সময়ে অবহেলিত হতে পারে" " ... এবং আমি
ওলেহের

@ ওলেহ প্রাইপিন যদি আমি উত্তর হিসাবে urllib.request.urlopen (url) ব্যবহার করি, খোলা (ফাইল_নাম, 'wb') আউট_ফাইলে হিসাবে: shutil.copyfileobj (প্রতিক্রিয়া, আউট_ফाइल) তবে আমি কীভাবে ক্যাচ স্টেটমেন্টে HTTP স্থিতি কোডটি খুঁজে পেতে পারি? ফাইলটি খুঁজে পাওয়া যায়নি?
রবার্ট আছমান

145

আমি requestsযখনই এইচটিটিপি অনুরোধের সাথে সম্পর্কিত কিছু চাই তখনই আমি প্যাকেজ ব্যবহার করি কারণ এর এপিআইটি শুরু করা খুব সহজ:

প্রথমে ইনস্টল করুন 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()

হাই, আমি ফাইল ডাউনলোডের জন্যও একই ধরণের কোড ব্যবহার করছি তবে কিছুটা সময় ব্যতিক্রম হ'ল যেমন - 'চারম্যাপ' কোডেক অক্ষরটি এনকোড করতে পারে না '0 u010c' ..... আপনি কি আমাকে
এটিতে

10

এখানে আমরা পাইথন 3 তে 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

আপনি সেই জন্য উইজেট ব্যবহার করতে পারেন যা জনপ্রিয় ডাউনলোড করার শেল সরঞ্জাম। 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

হ্যাঁ, অবশ্যই অনুরোধগুলি এইচটিটিপি অনুরোধ সম্পর্কিত কোনও ক্ষেত্রে ব্যবহার করার জন্য দুর্দান্ত প্যাকেজ। তবে আমাদের নীচে আগত তথ্যের এনকোডিং প্রকারের সাথে সাবধান হওয়া দরকার একটি উদাহরণ যা পার্থক্যটি ব্যাখ্যা করে which


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))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.