Pobierz Plik z Internetu w Pythonie 3

Tworzę program, który pobierzeplik JAR (java) z serwera www, poprzez odczytanie adresu URL określonego wplik jad tej samej gry/aplikacji. Używam Pythona 3.2.1

Udało mi się wyodrębnić adres URL pliku JAR z pliku JAD( każdy plik JAD zawiera adres URL do pliku JAR), ale jak możesz sobie wyobrazić, wyodrębnioną wartością jest type () string.

Oto odpowiednia Funkcja:

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

downloadFile(URL_from_file)

Jednak zawsze dostaję błąd mówiąc, że typ w powyższej funkcji muszą być bajty, a nie string. Próbowałem użyć adresu URL.encode ('utf-8'), a także bajty (URL, encoding= 'utf-8'), ale zawsze otrzymywałbym ten sam lub podobny błąd.

Więc w zasadzie moje pytanie brzmi jak pobrać plik z serwera, gdy URL jest przechowywany w typie string?

Author: Bo Milanovich, 2011-08-30

6 answers

Jeśli chcesz uzyskać zawartość strony internetowej do zmiennej, wystarczy read odpowiedź 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

Najprostszym sposobem na pobranie i zapisanie pliku jest użycie urllib.request.urlretrieve funkcja:

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)

Ale należy pamiętać, że urlretrieve jest uważany za dziedzictwo i może stać się przestarzały(choć Nie wiem dlaczego).

Więc najbardziej poprawnym sposobem na to byłoby użycie urllib.request.urlopen funkcja zwracająca obiekt podobny do pliku, który reprezentuje odpowiedź HTTP i kopiująca go do rzeczywistego pliku za pomocą 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)

Jeśli wydaje się to zbyt skomplikowane, możesz pójść prościej i zapisać cały pobrany plik w obiekcie bytes, a następnie zapisać go do pliku. Ale to działa dobrze tylko dla małych plików.

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)

Możliwe jest wyodrębnianie .gz (i być może innych formatów) skompresowanych danych w locie, ale taka operacja prawdopodobnie wymaga serwera HTTP do obsługi losowego dostępu do pliku.

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`.
 419
Author: Oleh Prypin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-26 09:32:58

Używam requests pakietu, gdy chcę czegoś związanego z żądaniami HTTP, ponieważ jego API jest bardzo łatwe do uruchomienia:

Najpierw zainstaluj requests

$ pip install requests

Następnie kod:

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)
 71
Author: Ali Faki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-05 14:13:27

Mam nadzieję, że dobrze zrozumiałem pytanie, które brzmi: jak pobrać plik z serwera, gdy URL jest przechowywany w typie string?

Pobieram pliki i zapisuję je lokalnie używając poniższego kodu:

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()
 13
Author: Ranvijay Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-18 20:32:35

Możesz użyć wget , który jest popularnym narzędziem do pobierania powłoki. https://pypi.python.org/pypi/wget Będzie to najprostsza metoda, ponieważ nie trzeba otwierać pliku docelowego. Oto przykład.

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') 
 3
Author: Lasith Niroshan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-13 19:39:14

Tutaj możemy użyć starszego interfejsu urllib w Python3:

Następujące funkcje i klasy są przeportowane z modułu urllib Pythona 2 (w przeciwieństwie do urllib2). Mogą one stać się przestarzałe w pewnym momencie w przyszłości.

Przykład (kod 2 linii):

import urllib.request

url = 'https://www.python.org/static/img/python-logo.png'
urllib.request.urlretrieve(url, "logo.png")
 2
Author: Yang Yu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-17 14:08:47
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))
 -3
Author: user7726287,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-17 09:35:56