返されたZipファイルをURLからダウンロードします


88

Webブラウザで送信するとダイアログボックスが表示されてzipファイルを保存するURLがある場合、Pythonでこのzipファイルをキャッチしてダウンロードするにはどうすればよいですか?


1
バイナリファイルをダウンロードして、chramとして機能するこのページのディスク書き込むセクションを試してみました。
Zeinab Abbasimazar 2018年

回答:


36

ほとんどの人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())

サンプルスニペットも追加していただけますか。そうすることはあなたにとても親切でしょう
SarvagyaDubey20年

207

私の知る限り、これを行う適切な方法は次のとおりです。

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

この答えをありがとう。これを使用して、リクエストを含むzipファイルを取得する問題を解決しました。
gr1zzly be4r 2016年

yoavram、あなたのコードで-私はどこにウェブページのURLを入力しますか?
newGIS 2016年

25
あなたが別の場所にダウンロードしたファイルを保存したい場合は、交換するz.extractall()z.extractall("/path/to/destination_directory")
user799188

1
URLからファイルを保存したいだけの場合は、次のことができますurllib.request.urlretrieve(url, filename)
yoavram 2018年

3
60分かかりすぎた点を他の人がつなぐのを助けるためpd.read_table(z.open('filename'))に、上記で使用できます。複数のファイルを含むzipURLリンクがあり、1つだけをロードすることに関心がある場合に便利です。
Frikster 2018

13

このブログ投稿の助けを借りて、私はそれをちょうどで動作させることができ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()

2
回答は、コンテンツの大部分をリンクに依存するべきではありません。リンクが切れたり、反対側のコンテンツが変更されて質問に答えられなくなったりする可能性があります。リンク先の情報の概要または説明を含めるように回答を編集してください。
mypetlion 2018

8

これが私が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.ですか?
ビクターMヘラスメペレス

@ 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
しかし、results.contentをzipでどのように解析しますか?
0atman 2012年

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パスは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()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.