454 Stimmen

Herunterladen von Dateien aus dem Internet in Python 3

Ich erstelle ein Programm, das eine .jar-Datei (Java) von einem Webserver herunterlädt, indem es die URL liest, die in der .jad-Datei des gleichen Spiels/der gleichen Anwendung angegeben ist. Ich verwende Python 3.2.1

Es ist mir gelungen, die URL der JAR-Datei aus der JAD-Datei zu extrahieren (jede JAD-Datei enthält die URL der JAR-Datei), aber wie Sie sich vielleicht vorstellen können, ist der extrahierte Wert ein type()-String.

Hier ist die entsprechende Funktion:

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

downloadFile(URL_from_file)

Allerdings erhalte ich immer eine Fehlermeldung, die besagt, dass der Typ in der obigen Funktion Bytes und nicht String sein muss. Ich habe versucht, URL.encode('utf-8') und auch bytes(URL,encoding='utf-8') zu verwenden, aber ich erhalte immer den gleichen oder einen ähnlichen Fehler.

Also im Grunde meine Frage ist, wie man eine Datei von einem Server herunterladen, wenn die URL in einem String-Typ gespeichert ist?

5voto

Kaushal Pahwani Punkte 444

Ja, definitiv Anfragen ist große Paket in etwas im Zusammenhang mit HTTP-Anfragen zu verwenden. aber wir müssen vorsichtig sein, mit der Codierung Typ der eingehenden Daten als auch unten ist ein Beispiel, das den Unterschied erklärt

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)

0voto

Carson Punkte 3411

Motivation

Manchmal möchten wir ein Bild erhalten, müssen es aber nicht in echte Dateien herunterladen,

d.h., die Daten herunterladen und im Speicher halten.

Wenn ich zum Beispiel die Methode des maschinellen Lernens verwende, trainiere ich ein Modell, das ein Bild mit einer Nummer (Strichcode) erkennen kann.

Wenn ich einige Websites durchsuche und diese Bilder habe, kann ich das Modell verwenden, um es zu erkennen,

und ich möchte diese Bilder nicht auf meinem Laufwerk speichern,

dann können Sie die folgende Methode ausprobieren, die Ihnen hilft, die heruntergeladenen Daten im Speicher zu behalten.

Punkte

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)

ist im Grunde wie bei @Ranvijay Kumar

Ein Beispiel

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()

-2voto

user7726287 Punkte 21
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))

-7voto

Wenn Sie Linux verwenden, können Sie die wget Modul von Linux über die Python-Shell. Hier ist ein Beispiel-Code-Schnipsel

import os
url = 'http://www.example.com/foo.zip'
os.system('wget %s'%url)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X