Jeśli mam adres URL, który po przesłaniu w przeglądarce internetowej wyskakuje okno dialogowe do zapisania pliku zip, jak powinienem przechwycić i pobrać ten plik zip w Pythonie?
Próbowałem punkt pobierania pliku binarnego i pisanie go na dysku z tej strony , która pracowała jako chram.
Zeinab Abbasimazar
Odpowiedzi:
36
Większość ludzi zaleca używanie, requestsjeśli jest dostępne, a requestsdokumentacja zaleca to do pobierania i zapisywania surowych danych z adresu URL:
import requests
defdownload_url(url, save_path, chunk_size=128):
r = requests.get(url, stream=True)
withopen(save_path, 'wb') as fd:
for chunk in r.iter_content(chunk_size=chunk_size):
fd.write(chunk)
Ponieważ odpowiedź zawiera pytanie o pobranie i zapisanie pliku zip, nie wdałem się w szczegóły dotyczące odczytu pliku zip. Zobacz jedną z wielu odpowiedzi poniżej, aby poznać możliwości.
Jeśli z jakiegoś powodu nie masz dostępu requests, możesz użyć urllib.requestzamiast tego. Może nie być tak solidne, jak powyższe.
import urllib.request
defdownload_url(url, save_path):with urllib.request.urlopen(url) as dl_file:
withopen(save_path, 'wb') as out_file:
out_file.write(dl_file.read())
Wreszcie, jeśli nadal używasz Pythona 2, możesz użyć urllib2.urlopen.
from contextlib import closing
defdownload_url(url, save_path):with closing(urllib2.urlopen(url)) as dl_file:
withopen(save_path, 'wb') as out_file:
out_file.write(dl_file.read())
yoavram, w swoim kodzie - gdzie wpisuję adres URL strony internetowej?
nowyGIS
25
Jeśli chcesz zapisać pobrany plik w innym miejscu, należy wymienić z.extractall()zz.extractall("/path/to/destination_directory")
user799188
1
Jeśli tylko chcesz zapisać plik z adresu URL można zrobić: urllib.request.urlretrieve(url, filename).
yoavram,
3
Aby pomóc innym połączyć kropki, zajęło mi to 60 minut za długo, możesz użyć pd.read_table(z.open('filename'))powyższego. Przydatne, jeśli masz link zip url zawierający wiele plików i chcesz tylko załadować jeden.
Frikster
13
Z pomocą tego posta na blogu udało mi się to po prostu requests. Rzecz w tym, że dziwne streamjest to, że nie musimy wywoływać contentdużych żądań, które wymagałyby przetworzenia wszystkich na raz, zatykając pamięć. streamUnika tego przez iteracja Dane jednym kawałku na raz.
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()
W większości treści odpowiedzi nie powinny opierać się na linkach. Linki mogą zgasnąć lub zawartość po drugiej stronie może zostać zmieniona, aby nie odpowiadać na pytanie. Zmień swoją odpowiedź, aby zawierała podsumowanie lub wyjaśnienie informacji, do których prowadzi łącze.
mypetlion
8
Oto, co mam do pracy w Pythonie 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()
Dzień dobry. Jak można uniknąć tego błędu 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, kod stanu odpowiedzi HTTP 302 oznacza, że strona została przeniesiona. Myślę, że problem, przed którym
stoisz,
5
Użyj urllib2.urlopen lub możesz spróbować użyć doskonałego Requestsmodułu i uniknąć bólów głowy urllib2:
Użyj zipfilemodułu: zip = zipfile.ZipFile(results.content). Następnie wystarczy analizować poprzez pliki użyciu ZipFile.namelist(), ZipFile.open()alboZipFile.extractall()
aravenel
5
Przyszedłem tutaj, szukając, jak zapisać plik .bzip2. Wkleję kod dla innych, którzy mogą tego szukać.
Dzięki @yoavram za powyższe rozwiązanie, moja ścieżka URL jest połączona ze spakowanym folderem i napotykam błąd BADZipfile (plik nie jest plikiem zip) i było dziwne, gdy próbowałem kilka razy, aby pobrać adres URL i rozpakować wszystko nagle więc poprawiam nieco rozwiązanie. używając metody is_zipfile , jak tutaj
r = requests.get(url, stream =True)
check = zipfile.is_zipfile(io.BytesIO(r.content))
whilenot 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()
Odpowiedzi:
Większość ludzi zaleca używanie,
requests
jeśli jest dostępne, arequests
dokumentacja zaleca to do pobierania i zapisywania surowych danych z adresu 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)
Ponieważ odpowiedź zawiera pytanie o pobranie i zapisanie pliku zip, nie wdałem się w szczegóły dotyczące odczytu pliku zip. Zobacz jedną z wielu odpowiedzi poniżej, aby poznać możliwości.
Jeśli z jakiegoś powodu nie masz dostępu
requests
, możesz użyćurllib.request
zamiast tego. Może nie być tak solidne, jak powyższe.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())
Wreszcie, jeśli nadal używasz Pythona 2, możesz użyć
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())
źródło
O ile wiem, właściwym sposobem na to jest:
import requests, zipfile, StringIO r = requests.get(zip_file_url, stream=True) z = zipfile.ZipFile(StringIO.StringIO(r.content)) z.extractall()
oczywiście chciałbyś sprawdzić, czy GET się powiódł
r.ok
.W przypadku Pythona 3+, podrzędny moduł StringIO z modułem io i użyj BytesIO zamiast StringIO: Oto uwagi do wydania, które wspominają o tej zmianie.
import requests, zipfile, io r = requests.get(zip_file_url) z = zipfile.ZipFile(io.BytesIO(r.content)) z.extractall("/path/to/destination_directory")
źródło
z.extractall()
zz.extractall("/path/to/destination_directory")
urllib.request.urlretrieve(url, filename)
.pd.read_table(z.open('filename'))
powyższego. Przydatne, jeśli masz link zip url zawierający wiele plików i chcesz tylko załadować jeden.Z pomocą tego posta na blogu udało mi się to po prostu
requests
. Rzecz w tym, że dziwnestream
jest to, że nie musimy wywoływaćcontent
dużych żądań, które wymagałyby przetworzenia wszystkich na raz, zatykając pamięć.stream
Unika tego przez iteracja Dane jednym kawałku na raz.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()
źródło
Oto, co mam do pracy w Pythonie 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()
źródło
urllib.error.HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop.
:?Użyj urllib2.urlopen lub możesz spróbować użyć doskonałego
Requests
modułu i uniknąć bólów głowy urllib2:import requests results = requests.get('url') #pass results.content onto secondary processing...
źródło
zipfile
modułu:zip = zipfile.ZipFile(results.content)
. Następnie wystarczy analizować poprzez pliki użyciuZipFile.namelist()
,ZipFile.open()
alboZipFile.extractall()
Przyszedłem tutaj, szukając, jak zapisać plik .bzip2. Wkleję kod dla innych, którzy mogą tego szukać.
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)
Chciałem tylko zapisać plik tak, jak jest.
źródło
Dzięki @yoavram za powyższe rozwiązanie, moja ścieżka URL jest połączona ze spakowanym folderem i napotykam błąd BADZipfile (plik nie jest plikiem zip) i było dziwne, gdy próbowałem kilka razy, aby pobrać adres URL i rozpakować wszystko nagle więc poprawiam nieco rozwiązanie. używając metody is_zipfile , jak tutaj
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()
źródło