Webブラウザで送信するとダイアログボックスが表示されてzipファイルを保存するURLがある場合、Pythonでこのzipファイルをキャッチしてダウンロードするにはどうすればよいですか?
Webブラウザで送信するとダイアログボックスが表示されてzipファイルを保存するURLがある場合、Pythonでこのzipファイルをキャッチしてダウンロードするにはどうすればよいですか?
回答:
ほとんどの人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ファイルの読み取りについては詳しく説明していません。可能性については、以下の多くの回答の1つを参照してください。
何らかの理由でにアクセスできない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モジュールとのStringIOの代わりにBytesIOを使用します。ここでは、この変更を言及リリースノートにはあります。
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'))
に、上記で使用できます。複数のファイルを含むzipURLリンクがあり、1つだけをロードすることに関心がある場合に便利です。
このブログ投稿の助けを借りて、私はそれをちょうどで動作させることができrequests
ます。奇妙なstream
ことのポイントは、content
大きなリクエストを呼び出す必要がないことです。これにより、すべてを一度に処理する必要があり、メモリが詰まります。stream
一度に1つのチャンクデータを反復処理することによって、これを回避します。
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()
これが私がPython3で作業するようになったものです。
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パスはzipフォルダーにリンクされました 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()