Tải xuống và lưu tập tin http cơ bản vào đĩa trong python?


159

Tôi mới biết về Python và tôi đã trải qua phần Hỏi & Đáp trên trang web này, để trả lời câu hỏi của tôi. Tuy nhiên, tôi là người mới bắt đầu và tôi cảm thấy khó hiểu một số giải pháp. Tôi cần một giải pháp rất cơ bản.

Ai đó có thể vui lòng giải thích một giải pháp đơn giản để 'Tải xuống tệp qua http' và 'Lưu nó vào đĩa, trong Windows' không?

Tôi cũng không chắc chắn làm thế nào để sử dụng các mô-đun shutil và os.

Tệp tôi muốn tải xuống dưới 500 MB và là tệp lưu trữ .gz. Nếu ai đó có thể giải thích cách trích xuất tệp lưu trữ và sử dụng các tệp trong đó, điều đó sẽ rất tuyệt!

Đây là một giải pháp một phần, mà tôi đã viết từ nhiều câu trả lời khác nhau:

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

Ai đó có thể chỉ ra lỗi (cấp độ mới bắt đầu) và giải thích bất kỳ phương pháp dễ dàng hơn để làm điều này?

Cảm ơn!

Câu trả lời:


206

Một cách rõ ràng để tải xuống một tập tin là:

import urllib

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

Điều này tải một tập tin từ một trang web và đặt tên cho nó file.gz. Đây là một trong những giải pháp yêu thích của tôi, từ Tải xuống hình ảnh qua urllib và python .

Ví dụ này sử dụng urllibthư viện và nó sẽ trực tiếp lấy tệp dưới dạng nguồn.


3
Được rồi cảm ơn! Nhưng có cách nào để làm cho nó hoạt động thông qua các yêu cầu?
arvindch

5
Có khả năng lưu trong /myfolder/file.gz không?
John Snow

17
Không có khả năng tốt hơn là tự mình thử nó, có thể? :) Tôi có thể làm thành công testfile.retrieve("http://example.com/example.rpm", "/tmp/test.rpm").
Dharmit

18
Điều này không được chấp nhận vì Python 3.3 và giải pháp urllib.request.urlretrieve (xem câu trả lời bên dưới) là cách 'hiện đại'
MichielB

1
Cách tốt nhất để thêm tên người dùng và mật khẩu vào mã này là gì? tks
Estefy

109

Như đã đề cập ở đây :

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

EDIT:Nếu bạn vẫn muốn sử dụng các yêu cầu, hãy xem câu hỏi này hoặc câu hỏi này .


1
urllib sẽ hoạt động, tuy nhiên, nhiều người dường như khuyên bạn nên sử dụng các yêu cầu hơn urllib. Tại sao vậy
arvindch

2
requestscực kỳ hữu ích so với urllibkhi làm việc với API REST. Trừ khi, bạn đang muốn làm nhiều hơn nữa, điều này nên được tốt.
dparpyani

Ok, bây giờ tôi đã đọc các liên kết bạn đã cung cấp cho yêu cầu sử dụng. Tôi bối rối về cách khai báo đường dẫn tệp, để lưu tải xuống. Làm thế nào để tôi sử dụng os và tắt cho việc này?
arvindch

62
Đối với Python3:import urllib.request urllib.request.urlretrieve(url, filename)
Flash

1
Tôi không thể trích xuất mã trạng thái http bằng cách này nếu tải xuống không thành công
Aashish Thite

34

Tôi sử dụng wget .

Thư viện đơn giản và tốt nếu bạn muốn ví dụ?

import wget

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

file_name = wget.download(file_url)

mô-đun wget hỗ trợ phiên bản python 2 và python 3


33

Bốn phương pháp sử dụng wget, urllib và 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 - Các cuộc gọi chức năng 4469882 (4469842 cuộc gọi nguyên thủy) trong 20.236 giây

testRequest2 - 8580 gọi hàm (8574 cuộc gọi nguyên thủy) trong 0,072 giây

testUrllib - 3810 cuộc gọi chức năng (3775 cuộc gọi nguyên thủy) trong 0,036 giây

testwget - chức năng gọi 3499 trong 0,020 giây


1
Làm thế nào bạn có được số lượng các cuộc gọi chức năng?
Abdelhak

28

Đối với Python3 + URLopener không được dùng nữa. Và khi sử dụng bạn sẽ gặp lỗi như dưới đây:

url_opener = urllib.URLopener () AttributionError: mô-đun 'urllib' không có thuộc tính 'URLopener'

Vì vậy, hãy thử:

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

1
Thật kỳ lạ ... Tại sao không ai bỏ phiếu cho câu trả lời này khi Python 2 không được dùng nữa và chỉ có giải pháp này mới hoạt động bình thường ...
wowkin2

1
Đã đồng ý! Tôi đã kéo tóc của tôi qua các giải pháp trước đó. Chúc tôi có thể upvote 200 lần!
Yechiel K

5

Giải pháp Windows kỳ lạ

import subprocess

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

1

Tôi đã bắt đầu con đường này bởi vì wget của ESX không được biên dịch bằng SSL và tôi muốn tải OVA từ trang web của nhà cung cấp trực tiếp lên máy chủ ESXi ở bên kia thế giới.

Tôi đã phải tắt tường lửa (lười biếng) / bật https bằng cách chỉnh sửa các quy tắc (phù hợp)

đã tạo tập lệnh 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)

Các thư viện ESXi được ghép nối xuống nhưng trình cài đặt chồn mã nguồn mở dường như sử dụng urllib cho https ... vì vậy nó đã truyền cảm hứng cho tôi đi theo con đường này


-5

Một cách sạch khác để lưu tệp là:

import csv
import urllib

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

Điều này có lẽ nên urllib.urlretrievehoặc urllib.URLopener().retrieve, không rõ ý của bạn ở đây.
đời

9
Tại sao bạn nhập csv nếu bạn chỉ đặt tên một tệp?
Azeezah M
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.