Завантажте повернутий ZIP-файл із URL-адреси


85

Якщо у мене є URL-адреса, яка при надсиланні у веб-браузері відкриває діалогове вікно для збереження zip-файлу, як би я почав ловити та завантажувати цей zip-файл у Python?


1
Я спробував розділ Завантаження двійкового файлу і запису його на диск з цієї сторінки , яка працювала як chrám.
Зейнаб Аббасімазар

Відповіді:


32

Більшість людей рекомендують використовувати, requestsякщо він доступний, а requests документація рекомендує це для завантаження та збереження необроблених даних з 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)

Оскільки відповідь запитує про завантаження та збереження zip-файлу, я не вдався в подробиці щодо читання zip-файлу. Дивіться одну з багатьох відповідей нижче щодо можливостей.

Якщо з якихось причин у вас немає доступу requests, urllib.requestзамість цього ви можете використовувати . Це може бути не настільки надійним, як вище.

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())

Нарешті, якщо ви все ще використовуєте Python 2, ви можете використовувати 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())

Ви можете також додати зразок фрагмента. Це було б дуже люб’язно з вашого боку
Сарвагія Дубей,

205

Наскільки я можу зрозуміти, правильний спосіб зробити це:

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

звичайно, ви хочете перевірити, чи GET був успішним r.ok.

Для python 3+ доповніть модуль StringIO модулем io і використовуйте BytesIO замість StringIO: Ось примітки до випуску, в яких згадується ця зміна.

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

Дякую за цю відповідь. Я використав його для вирішення своєї проблеми з отриманням zip-файлу із запитами .
gr1zzly be4r

yoavram, у вашому коді - де я ввожу URL-адресу веб-сторінки?
newGIS

25
Якщо ви хочете зберегти завантажений файл в іншому місці, замініть z.extractall()наz.extractall("/path/to/destination_directory")
user799188

1
Якщо ви просто хочете зберегти файл з URL ви можете зробити: urllib.request.urlretrieve(url, filename).
йоаврам

3
Щоб допомогти іншим з’єднати точки, мені знадобилося 60 хвилин занадто довго, тоді ви можете скористатися pd.read_table(z.open('filename'))вищезазначеним. Корисно, якщо у вас є посилання на zip-адресу, що містить кілька файлів, і вас цікавить лише завантаження одного.
Фрікстер,

12

За допомогою цього допису в блозі я з ним працюю requests. Суть дивного streamполягає в тому, що нам не потрібно звертатися contentдо великих запитів, які вимагали б, щоб усі вони були оброблені відразу, засмічуючи пам’ять. streamУникає цього перебору даних один шматка за один раз.

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
Більшість відповідей не повинні покладатися на посилання. Посилання можуть загинути, або вміст з іншого боку може бути змінений, щоб більше не відповідати на питання. Будь ласка, відредагуйте свою відповідь, включивши короткий виклад або пояснення інформації, на яку вказуєте посилання.
mypetlion

7

Ось що я мав працювати в 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.:?
Victor M Herasme Perez

@VictorHerasmePerez, код стану відповіді HTTP 302 означає, що сторінку переміщено. Я думаю , що питання ваш облицювальні адресований тут: stackoverflow.com/questions/32569934 / ...
Webucator

5

Або використовуйте urllib2.urlopen, або ви можете спробувати використовувати чудовий Requestsмодуль і уникнути головного болю urllib2:

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

1
Але як аналізувати result.content int zip?
0atman

Використовуйте zipfileмодуль: zip = zipfile.ZipFile(results.content). Потім просто розібрати через файли , використовуючи ZipFile.namelist(), ZipFile.open()абоZipFile.extractall()
aravenel

5

Я прийшов сюди, шукаючи, як зберегти файл .bzip2. Дозвольте мені вставити код для інших, хто може прийти шукати це.

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)

Я просто хотів зберегти файл як є.


3

Завдяки @yoavram за вищезазначене рішення, мій шлях до URL-адреси пов’язаний із заархівованою папкою , і зіткнувся з помилкою BADZipfile (файл не є ZIP-файлом), і було дивно, якщо я спробував кілька разів отримати URL-адресу та розпакувати все раптово, тому я трохи поправляю рішення. використовуючи метод is_zipfile відповідно до цього

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()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.