Завантаження основного http-файлу та збереження його на диску в python?


159

Я новачок у Python, і я пережив питання і відповіді на цьому сайті, щоб отримати відповідь на своє запитання. Однак я початківець і мені важко зрозуміти деякі рішення. Мені потрібно дуже базове рішення.

Чи можете мені хтось пояснити просте рішення «Завантажити файл через http» та «Зберегти його на диску в Windows»?

Я не впевнений, як використовувати shutil і os модулі.

Файл, який я хочу завантажити, становить менше 500 МБ і є .gz архівним файлом. Якщо хтось може пояснити, як витягнути архів і також використовувати в ньому файли, це було б чудово!

Ось часткове рішення, яке я писав з різних відповідей разом:

import requests
import os
import shutil

global dump

def download_file():
    global dump
    url = "http://randomsite.com/file.gz"
    file = requests.get(url, stream=True)
    dump = file.raw

def save_file():
    global dump
    location = os.path.abspath("D:\folder\file.gz")
    with open("file.gz", 'wb') as location:
        shutil.copyfileobj(dump, location)
    del dump

Чи може хтось вказати на помилки (початковий рівень) та пояснити будь-які простіші методи для цього?

Дякую!

Відповіді:


207

Чистий спосіб завантажити файл:

import urllib

testfile = urllib.URLopener()
testfile.retrieve("http://randomsite.com/file.gz", "file.gz")

При цьому завантажується файл із веб-сайту та називається його file.gz. Це одне з моїх улюблених рішень - із завантаження картинки через urllib та python .

У цьому прикладі використовується urllibбібліотека, і він безпосередньо отримає файл із джерела.


3
Добре, дякую! Але чи є спосіб змусити це працювати через запити?
arvindch

5
Будь-яка можливість зберегти в /myfolder/file.gz?
Джон Сноу

17
Немає кращої можливості, ніж спробувати його, можливо? :) Я міг би успішно це зробити testfile.retrieve("http://example.com/example.rpm", "/tmp/test.rpm").
Дхарміт

18
Це застаріле з моменту Python 3.3, а рішення urllib.request.urlretrieve (див. Відповідь нижче) є "сучасним" способом
MichielB

1
Який найкращий спосіб додати ім’я користувача та пароль до цього коду? tks
Estefy

110

Як згадувалося тут :

import urllib
urllib.urlretrieve ("http://randomsite.com/file.gz", "file.gz")

EDIT:Якщо ви все ще хочете використовувати запити, погляньте на це або це запитання .


1
urllib працюватиме, однак, здається, багато людей рекомендують використовувати запити над urllib. Чому це?
arvindch

2
requestsнадзвичайно корисний у порівнянні з urllibроботою з REST API. Якщо ви хочете зробити набагато більше, це повинно бути добре.
dparpyani

Гаразд, зараз я прочитав посилання, які ви надали для використання запитів. Мене бентежить питання про те, як оголосити шлях до файлу для збереження завантаження. Як я можу використовувати для цього os та shutil?
arvindch

62
Для Python3:import urllib.request urllib.request.urlretrieve(url, filename)
Flash

1
Я не можу витягти код коду статусу за допомогою цього, якщо завантаження не
вдалося

34

Я використовую wget .

Проста і хороша бібліотека, якщо ви хочете зробити приклад?

import wget

file_url = 'http://johndoe.com/download.zip'

file_name = wget.download(file_url)

Підтримка модулів wget підтримує версії python 2 та python 3


33

Чотири методи за допомогою wget, urllib та request.

#!/usr/bin/python
import requests
from StringIO import StringIO
from PIL import Image
import profile as profile
import urllib
import wget


url = 'https://tinypng.com/images/social/website.jpg'

def testRequest():
    image_name = 'test1.jpg'
    r = requests.get(url, stream=True)
    with open(image_name, 'wb') as f:
        for chunk in r.iter_content():
            f.write(chunk)

def testRequest2():
    image_name = 'test2.jpg'
    r = requests.get(url)
    i = Image.open(StringIO(r.content))
    i.save(image_name)

def testUrllib():
    image_name = 'test3.jpg'
    testfile = urllib.URLopener()
    testfile.retrieve(url, image_name)

def testwget():
    image_name = 'test4.jpg'
    wget.download(url, image_name)

if __name__ == '__main__':
    profile.run('testRequest()')
    profile.run('testRequest2()')
    profile.run('testUrllib()')
    profile.run('testwget()')

testRequest - 4469882 виклик функцій (4469842 примітивні дзвінки) за 20,236 секунди

testRequest2 - 8580 функціональних дзвінків (8574 примітивних дзвінків) за 0,072 секунди

testUrllib - 3810 функціональних дзвінків (3775 примітивних дзвінків) за 0,036 секунди

testwget - 3489 функціональних дзвінків за 0,020 секунд


1
Як ви отримали кількість викликів функцій?
Абдельхак

29

Для Python3 + URLopener застаріле. При використанні ви отримаєте помилку, як показано нижче:

url_opener = urllib.URLopener () AttributeError: модуль 'urllib' не має атрибута 'URLopener'

Отже, спробуйте:

import urllib.request 
urllib.request.urlretrieve(url, filename)

1
Дивно ... Чому ніхто не голосує за цю відповідь, коли Python 2 застарів і лише це рішення повинно працювати належним чином ...
wowkin2

1
Домовились! Я натягував волосся на попередні рішення. Бажаю, щоб я міг подати 200 разів!
Єхієль К

5

Екзотичне рішення для Windows

import subprocess

subprocess.run("powershell Invoke-WebRequest {} -OutFile {}".format(your_url, filename), shell=True)

1

Я почав цей шлях, тому що wget ESXi не компілюється з SSL, і я хотів завантажити OVA з веб-сайту постачальника безпосередньо на хост ESXi, який знаходиться з іншого боку світу.

Мені довелося вимкнути брандмауер (ледачий) / включити https, редагуючи правила (належне)

створив сценарій python:

import ssl
import shutil
import tempfile
import urllib.request
context = ssl._create_unverified_context()

dlurl='https://somesite/path/whatever'
with urllib.request.urlopen(durl, context=context) as response:
    with open("file.ova", 'wb') as tmp_file:
        shutil.copyfileobj(response, tmp_file)

Бібліотеки ESXi начебто спарені, але інсталятор з відкритим кодом ніс використовував urllib для https ... тож це надихнуло мене піти цим шляхом


-5

Ще один чистий спосіб збереження файлу:

import csv
import urllib

urllib.retrieve("your url goes here" , "output.csv")

Це, мабуть, має бути urllib.urlretrieveабо urllib.URLopener().retrieveнезрозуміло, що ви тут мали на увазі.
товариш

9
Чому ви імпортуєте файл csv, якщо ви просто називаєте файл?
Azeeza M
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.