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?
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?
Câu trả lời:
Hầu hết mọi người khuyên bạn nên sử dụng requests
nế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.request
thay 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())
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")
z.extractall()
vớiz.extractall("/path/to/destination_directory")
urllib.request.urlretrieve(url, filename)
.
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.
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ạ stream
là chúng ta không cần phải gọi content
cá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 stream
nà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()
Đâ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()
urllib.error.HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop.
:?
Hoặc sử dụng urllib2.urlopen, hoặc bạn có thể thử sử dụng Requests
mô-đun tuyệt vời và tránh đau đầu urllib2:
import requests
results = requests.get('url')
#pass results.content onto secondary processing...
zipfile
mô-đ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()
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.
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()