Tải xuống tệp Zip đã trả lại từ URL


84

Nếu tôi có một URL mà khi được gửi trong trình duyệt web, sẽ bật lên một hộp thoại để lưu tệp zip, tôi sẽ làm cách nào để bắt và tải xuống tệp zip này bằng Python?


1
Tôi đã thử phần Tải xuống tệp nhị phân và ghi nó vào đĩa của trang này hoạt động dưới dạng chram.
Zeinab Abbasimazar

Câu trả lời:


32

Hầu hết mọi người khuyên bạn nên sử dụng requestsnếu nó có sẵn và requests tài liệu khuyến nghị điều này để tải xuống và lưu dữ liệu thô từ url:

import requests 

def download_url(url, save_path, chunk_size=128):
    r = requests.get(url, stream=True)
    with open(save_path, 'wb') as fd:
        for chunk in r.iter_content(chunk_size=chunk_size):
            fd.write(chunk)

Vì câu trả lời hỏi về việc tải xuống và lưu tệp zip nên tôi chưa đi sâu vào chi tiết liên quan đến việc đọc tệp zip. Xem một trong nhiều câu trả lời bên dưới để biết các khả năng.

Nếu vì lý do nào đó bạn không có quyền truy cập requests, bạn có thể sử dụng urllib.requestthay thế. Nó có thể không hoàn toàn mạnh mẽ như ở trên.

import urllib.request

def download_url(url, save_path):
    with urllib.request.urlopen(url) as dl_file:
        with open(save_path, 'wb') as out_file:
            out_file.write(dl_file.read())

Cuối cùng, nếu bạn vẫn đang sử dụng Python 2, bạn có thể sử dụng urllib2.urlopen.

from contextlib import closing

def download_url(url, save_path):
    with closing(urllib2.urlopen(url)) as dl_file:
        with open(save_path, 'wb') as out_file:
            out_file.write(dl_file.read())

Bạn có thể vui lòng thêm đoạn mã mẫu được không. Bạn thật tốt khi làm như vậy
Sarvagya Dubey

203

Theo như tôi có thể nói, cách thích hợp để làm điều này là:

import requests, zipfile, StringIO
r = requests.get(zip_file_url, stream=True)
z = zipfile.ZipFile(StringIO.StringIO(r.content))
z.extractall()

tất nhiên bạn muốn kiểm tra xem GET có thành công hay không r.ok.

Đối với python 3+, hãy phụ mô-đun StringIO bằng mô-đun io và sử dụng BytesIO thay vì StringIO: Dưới đây là ghi chú phát hành đề cập đến thay đổi này.

import requests, zipfile, io
r = requests.get(zip_file_url)
z = zipfile.ZipFile(io.BytesIO(r.content))
z.extractall("/path/to/destination_directory")

Cảm ơn vì câu trả lời này. Tôi đã sử dụng nó để giải quyết vấn đề của mình khi nhận được tệp zip có yêu cầu .
gr1zzly be4r

yoavram, trong mã của bạn- nơi tôi nhập url của trang web?
newGIS

25
Nếu bạn muốn lưu các tập tin tải về ở một vị trí khác nhau, thay thế z.extractall()vớiz.extractall("/path/to/destination_directory")
user799188

1
Nếu bạn chỉ muốn lưu các tập tin từ url mà bạn có thể làm: urllib.request.urlretrieve(url, filename).
yoavram

3
Để giúp những người khác kết nối các dấu chấm mà tôi đã mất 60 phút quá lâu, sau đó bạn có thể sử dụng pd.read_table(z.open('filename'))các bước trên. Hữu ích nếu bạn có một liên kết url zip chứa nhiều tệp và bạn chỉ muốn tải một tệp.
Frikster

12

Với sự trợ giúp của bài đăng blog này , tôi đã làm cho nó hoạt động requests. Điều kỳ lạ streamlà chúng ta không cần phải gọi contentcác yêu cầu lớn, yêu cầu này phải được xử lý tất cả cùng một lúc, gây tắc nghẽn bộ nhớ. Tính năng streamnày tránh điều này bằng cách lặp lại từng đoạn dữ liệu một.

url = 'https://www2.census.gov/geo/tiger/GENZ2017/shp/cb_2017_02_tract_500k.zip'
target_path = 'alaska.zip'

response = requests.get(url, stream=True)
handle = open(target_path, "wb")
for chunk in response.iter_content(chunk_size=512):
    if chunk:  # filter out keep-alive new chunks
        handle.write(chunk)
handle.close()

2
Các câu trả lời không nên dựa vào các liên kết cho phần lớn nội dung của chúng. Các liên kết có thể ngừng hoạt động hoặc nội dung ở phía bên kia có thể bị thay đổi để không còn trả lời câu hỏi. Vui lòng chỉnh sửa câu trả lời của bạn để bao gồm bản tóm tắt hoặc giải thích thông tin mà bạn liên kết trỏ đến.
mypetlion,

7

Đây là những gì tôi phải làm việc trong Python 3:

import zipfile, urllib.request, shutil

url = 'http://www....myzipfile.zip'
file_name = 'myzip.zip'

with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
    shutil.copyfileobj(response, out_file)
    with zipfile.ZipFile(file_name) as zf:
        zf.extractall()

Xin chào. Làm thế nào để tránh lỗi này urllib.error.HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop.:?
Victor M Herasme Perez,

@VictorHerasmePerez, mã trạng thái phản hồi HTTP 302 có nghĩa là trang đã được di chuyển. Tôi nghĩ vấn đề bạn gặp phải được giải quyết ở đây: stackoverflow.com/questions/32569934/…
Webucator

5

Hoặc sử dụng urllib2.urlopen, hoặc bạn có thể thử sử dụng Requestsmô-đun tuyệt vời và tránh đau đầu urllib2:

import requests
results = requests.get('url')
#pass results.content onto secondary processing...

1
Nhưng làm cách nào để bạn phân tích cú pháp results.content thành một tệp zip?
0atman

Sử dụng các zipfilemô-đun: zip = zipfile.ZipFile(results.content). Sau đó chỉ cần phân tích cú pháp thông qua các tập tin sử dụng ZipFile.namelist(), ZipFile.open()hoặcZipFile.extractall()
aravenel

5

Tôi đến đây để tìm kiếm cách lưu tệp .bzip2. Hãy để tôi dán mã cho những người khác có thể tìm kiếm cái này.

url = "http://api.mywebsite.com"
filename = "swateek.tar.gz"

response = requests.get(url, headers=headers, auth=('myusername', 'mypassword'), timeout=50)
if response.status_code == 200:
with open(filename, 'wb') as f:
   f.write(response.content)

Tôi chỉ muốn lưu tệp như hiện tại.


3

Cảm ơn @yoavram về giải pháp trên, đường dẫn url của tôi được liên kết với một thư mục nén và gặp phải lỗi BADZipfile (tệp không phải là tệp zip) và thật kỳ lạ nếu tôi đã thử nhiều lần nó vẫn truy xuất url và giải nén tất cả. đột ngột vì vậy tôi sửa đổi giải pháp một chút. sử dụng phương thức is_zipfile theo đây

r = requests.get(url, stream =True)
check = zipfile.is_zipfile(io.BytesIO(r.content))
while not check:
    r = requests.get(url, stream =True)
    check = zipfile.is_zipfile(io.BytesIO(r.content))
else:
    z = zipfile.ZipFile(io.BytesIO(r.content))
    z.extractall()
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.