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!

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.


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 .


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


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


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)

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)

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


-5

Cara bersih lain untuk menyimpan file adalah ini:

import csv
import urllib

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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.