Download básico de arquivo http e salvamento em disco em python?

159

Eu sou novo no Python e tenho feito perguntas e respostas neste site, para obter uma resposta para minha pergunta. No entanto, sou iniciante e acho difícil entender algumas das soluções. Eu preciso de uma solução muito básica.

Alguém poderia, por favor, explicar uma solução simples para 'Baixar um arquivo através de http' e 'Salvá-lo em disco no Windows' para mim?

Também não sei como usar os módulos shutil e os.

O arquivo que eu quero baixar tem menos de 500 MB e é um arquivo .gz. Se alguém puder explicar como extrair o arquivo e utilizar os arquivos nele, isso seria ótimo!

Aqui está uma solução parcial, que escrevi de várias respostas combinadas:

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

Alguém poderia apontar erros (nível iniciante) e explicar métodos mais fáceis de fazer isso?

Obrigado!

arvindch
fonte

Respostas:

206

Uma maneira limpa de baixar um arquivo é:

import urllib

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

Isso baixa um arquivo de um site e o nomeia file.gz. Esta é uma das minhas soluções favoritas, de Download de uma imagem via urllib e python .

Este exemplo usa a urllibbiblioteca e recupera diretamente o arquivo de uma origem.

Gelo azul
fonte
3
Ok, obrigada! Mas existe uma maneira de fazê-lo funcionar através de solicitações?
Arvindch #
5
Alguma possibilidade de salvar em /myfolder/file.gz?
John Snow
17
Não há melhor possibilidade do que tentar você mesmo, talvez? :) Eu poderia fazer com sucesso testfile.retrieve("http://example.com/example.rpm", "/tmp/test.rpm").
Dharmit
18
Isto está obsoleto desde o Python 3.3, e a solução urllib.request.urlretrieve (veja resposta abaixo) é a maneira 'moderna'
MichielB
1
Qual é a melhor maneira de adicionar um nome de usuário e senha a este código? tks
Estefy 17/09/17
109

Como mencionado aqui :

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

EDIT:Se você ainda deseja usar solicitações, consulte esta pergunta ou esta .

dparpyani
fonte
1
O urllib funcionará, no entanto, muitas pessoas parecem recomendar o uso de solicitações sobre o urllib. Por que isso?
Arvindch #
2
requestsé extremamente útil em comparação com o urllibtrabalho com uma API REST. A menos que você esteja procurando fazer muito mais, isso deve ser bom.
dparpyani
Ok, agora eu li os links que você forneceu para o uso de solicitações. Estou confuso sobre como declarar o caminho do arquivo, para salvar o download. Como uso o os e shutil para isso?
Arvindch #
62
Para Python3:import urllib.request urllib.request.urlretrieve(url, filename)
Flash
1
Eu não sou capaz de extrair o código de status http com isso, se o download falhar
Aashish Thite
34

Eu uso o wget .

Biblioteca simples e boa, se você quiser dar um exemplo?

import wget

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

file_name = wget.download(file_url)

O módulo wget suporta as versões python 2 e python 3

Todos
fonte
33

Quatro métodos usando wget, urllib e 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 chamadas de função (4469842 chamadas primitivas) em 20,236 segundos

testRequest2 - 8580 chamadas de função (8574 chamadas primitivas) em 0,072 segundos

testUrllib - 3810 chamadas de função (3775 chamadas primitivas) em 0,036 segundos

testwget - 3489 chamadas de função em 0,020 segundos

Saurabh yadav
fonte
1
Como você conseguiu o número de chamadas de função?
Abdelhak 02/09
28

Para Python3 + URLopener está obsoleto. E quando usado, você receberá um erro como abaixo:

url_opener = urllib.URLopener () AttributeError: o módulo 'urllib' não tem atributo 'URLopener'

Então tente:

import urllib.request 
urllib.request.urlretrieve(url, filename)
Om Sao
fonte
1
Estranho ... Por que ninguém votos para esta resposta quando Python 2 tornou-se obsoleto e só esta solução deve funcionar corretamente ...
wowkin2
1
Acordado! Eu estava puxando meu cabelo sobre as soluções anteriores. Gostaria de poder votar 200 vezes!
Yechiel K
5

Solução exótica para Windows

import subprocess

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

Comecei nesse caminho porque o wget do ESXi não é compilado com SSL e eu queria baixar um OVA do site de um fornecedor diretamente no host ESXi, que fica do outro lado do mundo.

Eu tive que desativar o firewall (lento) / ativar https fora editando as regras (apropriado)

criou o script 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)

As bibliotecas ESXi estão meio emparelhadas, mas o instalador de doninhas de código aberto parecia usar urllib para https ... então isso me inspirou a seguir esse caminho

Jayme Snyder
fonte
-5

Outra maneira limpa de salvar o arquivo é:

import csv
import urllib

urllib.retrieve("your url goes here" , "output.csv")
Ala
fonte
Provavelmente isso deveria ser urllib.urlretrieveou urllib.URLopener().retrieve, pouco claro, o que você quis dizer aqui.
mateor
9
Por que você importa o csv se está apenas nomeando um arquivo?
Azeezah M