Mengunduh dan menyimpan file http dasar ke disk dengan python?

159

Saya baru mengenal Python dan saya telah melalui T&J di situs ini, untuk jawaban atas pertanyaan saya. Namun, saya seorang pemula dan saya merasa sulit untuk memahami beberapa solusi. Saya butuh solusi yang sangat mendasar.

Bisakah seseorang tolong jelaskan solusi sederhana untuk 'Mengunduh file melalui http' dan 'Menyimpannya ke disk, di Windows', kepada saya?

Saya juga tidak yakin bagaimana menggunakan modul shutil dan os.

File yang ingin saya unduh adalah di bawah 500 MB dan merupakan file arsip .gz. Jika seseorang dapat menjelaskan cara mengekstrak arsip dan menggunakan file di dalamnya, itu akan menjadi luar biasa!

Inilah solusi parsial, yang saya tulis dari berbagai jawaban yang digabungkan:

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

Bisakah seseorang menunjukkan kesalahan (tingkat pemula) dan menjelaskan metode yang lebih mudah untuk melakukan ini?

Terima kasih!

arvindch
sumber

Jawaban:

207

Cara bersih untuk mengunduh file adalah:

import urllib

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

Ini mengunduh file dari situs web dan menamainya file.gz. Ini adalah salah satu solusi favorit saya, dari Mengunduh gambar melalui urllib dan python .

Contoh ini menggunakan urllibperpustakaan, dan itu akan langsung mengambil file dari sumber.

Es biru
sumber
3
Ok terima kasih! Tetapi apakah ada cara untuk membuatnya bekerja melalui permintaan?
arvindch
5
Adakah kemungkinan untuk menyimpan di /myfolder/file.gz?
John Snow
17
Tidak ada kemungkinan yang lebih baik daripada mencobanya sendiri, mungkin? :) Saya bisa berhasil melakukannya testfile.retrieve("http://example.com/example.rpm", "/tmp/test.rpm").
Dharmit
18
Ini sudah ditinggalkan sejak Python 3.3, dan solusi urllib.request.urlretrieve (lihat jawaban di bawah) adalah cara 'modern'
MichielB
1
Apa cara terbaik untuk menambahkan nama pengguna dan kata sandi ke kode ini? tks
Estefy
110

Seperti yang disebutkan di sini :

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

EDIT:Jika Anda masih ingin menggunakan permintaan, lihat pertanyaan ini atau yang ini .

dparpyani
sumber
1
urllib akan berfungsi, namun, banyak orang tampaknya merekomendasikan penggunaan permintaan di atas urllib. Kenapa begitu?
arvindch
2
requestssangat membantu dibandingkan urllibsaat bekerja dengan REST API. Kecuali, Anda ingin melakukan lebih banyak, ini seharusnya bagus.
dparpyani
Oke, sekarang saya sudah membaca tautan yang Anda berikan untuk permintaan penggunaan. Saya bingung tentang cara mendeklarasikan path file, untuk menyimpan unduhan. Bagaimana saya menggunakan os dan shutil untuk ini?
arvindch
62
Untuk Python3:import urllib.request urllib.request.urlretrieve(url, filename)
Flash
1
Saya tidak dapat mengekstrak kode status http dengan ini jika unduhan gagal
Aashish Thite
34

Saya menggunakan wget .

Perpustakaan sederhana dan bagus jika Anda ingin contoh?

import wget

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

file_name = wget.download(file_url)

modul wget mendukung versi python 2 dan python 3

Ali
sumber
33

Empat metode menggunakan wget, urllib, dan 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 - panggilan fungsi 4469882 (4469842 panggilan primitif) dalam 20,236 detik

testRequest2 - 8580 panggilan fungsi (8574 panggilan primitif) dalam 0,072 detik

testUrllib - 3810 panggilan fungsi (3775 panggilan primitif) dalam 0,036 detik

testwget - 3489 panggilan fungsi dalam 0,020 detik

Saurabh yadav
sumber
1
Bagaimana Anda mendapatkan jumlah panggilan fungsi?
Abdelhak
30

Untuk Python3 + URLopener sudah usang. Dan ketika digunakan Anda akan mendapatkan kesalahan seperti di bawah ini:

url_opener = urllib.URLopener () AttributeError: module 'urllib' tidak memiliki atribut 'URLopener'

Jadi, coba:

import urllib.request 
urllib.request.urlretrieve(url, filename)
Om Sao
sumber
1
Aneh ... Mengapa tidak ada yang memberikan suara untuk jawaban ini ketika Python 2 menjadi usang dan hanya solusi ini yang akan berfungsi dengan baik ...
wowkin2
1
Sepakat! Saya menarik rambut saya ke solusi sebelumnya. Seandainya aku bisa menang 200 kali!
Yechiel K
5

Solusi Windows Eksotis

import subprocess

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

Saya memulai jalur ini karena wget ESXi tidak dikompilasi dengan SSL dan saya ingin mengunduh OVA dari situs web vendor langsung ke host ESXi yang ada di sisi lain dunia.

Saya harus menonaktifkan firewall (malas) / mengaktifkan https dengan mengedit aturan (semestinya)

membuat skrip 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)

Pustaka ESXi agak dipasangkan tetapi installer musang sumber terbuka tampaknya menggunakan urllib untuk https ... jadi itu mengilhami saya untuk mengikuti jalan ini

Jayme Snyder
sumber
-5

Cara bersih lain untuk menyimpan file adalah ini:

import csv
import urllib

urllib.retrieve("your url goes here" , "output.csv")
Ala
sumber
Ini mungkin urllib.urlretrieveatau urllib.URLopener().retrievetidak jelas yang Anda maksud di sini.
mateor
9
Mengapa Anda mengimpor csv jika Anda hanya memberi nama file?
Azeezah M