Если у меня есть URL-адрес, который при отправке в веб-браузере открывает диалоговое окно для сохранения zip-файла, как я могу поймать и загрузить этот zip-файл в Python?
Если у меня есть URL-адрес, который при отправке в веб-браузере открывает диалоговое окно для сохранения zip-файла, как я могу поймать и загрузить этот zip-файл в Python?
Ответы:
Большинство людей рекомендуют использовать, 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())
Насколько я могу судить, правильный способ сделать это:
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")
z.extractall()
наz.extractall("/path/to/destination_directory")
urllib.request.urlretrieve(url, filename)
.
pd.read_table(z.open('filename'))
с указанным выше. Полезно, если у вас есть ссылка на zip-адрес, содержащая несколько файлов, и вас интересует только загрузка одного.
С помощью этого сообщения в блоге я получил возможность работать с просто 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()
Вот что мне нужно для работы в 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.
:?
Либо используйте urllib2.urlopen, либо вы можете попробовать использовать отличный Requests
модуль и избежать головной боли urllib2:
import requests
results = requests.get('url')
#pass results.content onto secondary processing...
zipfile
модуль: zip = zipfile.ZipFile(results.content)
. Затем просто разобрать через файлы , используя ZipFile.namelist()
, ZipFile.open()
илиZipFile.extractall()
Я пришел сюда искать, как сохранить файл .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)
Я просто хотел сохранить файл как есть.
Благодаря @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()