web-dev-qa-db-ja.com

Pythonでは、GZIPエンコーディングをどのようにデコードしますか?

pythonスクリプトでWebページをダウンロードしました。ほとんどの場合、これは正常に機能します。

ただし、これには応答ヘッダーGZIPエンコードがあり、このWebページのソースコードを印刷しようとしたときに、PuTTYにすべてのシンボルが含まれていました。

これを通常のテキストにどのようにデコードしますか?

39
TIMEX

Zlibを使用して、gzip圧縮されたコンテンツをWebから解凍します。

import zlib

...
# f=urllib2.urlopen(url) 
decompressed_data=zlib.decompress(f.read(), 16+zlib.MAX_WBITS)
79
YOU

組み込みのgzipモジュールを使用して、バイトストリームを解凍します。

問題がある場合は、使用した正確な最小コード、正確なエラーメッセージ、トレースバック、およびprint repr(your_byte_stream[:100])の結果を表示してください

詳細情報

1。gzip/zlib/deflateの混乱の説明については、 このWikipediaの記事 の「その他の用途」セクションを参照してください。 。

2。ファイルではなく文字列がある場合、gzipモジュールよりもzlibモジュールを使用する方が簡単です。残念ながら Pythonドキュメント は不完全/間違っています:

"" "zlib.decompress(string [、wbits [、bufsize]])... wbitsの絶対値は、データの圧縮時に使用される履歴バッファーのサイズ(「ウィンドウサイズ」)の2を底とする対数です。 zlibライブラリの最新バージョンでは、絶対値は8〜15である必要があり、値を大きくすると圧縮率が向上しますが、メモリ使用量が増えます。デフォルト値は15です。wbitsが負の場合、標準gzipヘッダーは抑制されますこれは文書化されていないzlibライブラリの機能で、unzipの圧縮ファイル形式との互換性のために使用されます。

まず、8 <= log2_window_size <= 15で、上記の意味があります。次に、別の引数であるべきものを上で細かく調べます:

arg == log2_window_sizeは、文字列がzlib形式(RFC 1950; HTTP 1.1 RFC 2616が混乱して「deflate」と呼ぶもの)であると仮定することを意味します。

arg == -log2_window_sizeは、文字列がデフレート形式であると想定することを意味します(RFC 1951; HTTP 1.1 RFCを読んでいない人々が実際に実装したもの)

arg == 16 + log_2_window_sizeは、文字列がgzip形式であると想定することを意味します(RFC 1952)。したがって、31を使用できます。

上記の情報は zlib Cライブラリのマニュアル ...に記載されています。Ctrl-FでwindowBitsを検索します。

30
John Machin

私はそのようなものを使用します:

f = urllib2.urlopen(request)
data = f.read()
try:
    from cStringIO import StringIO
    from gzip import GzipFile
    data2 = GzipFile('', 'r', 0, StringIO(data)).read()
    data = data2
except:
    #print "decompress error %s" % err
    pass
return data
11
Michał Niklas

Python 3

これを試してください:

import gzip

fetch = opener.open(request) # basically get a response object
data = gzip.decompress(fetch.read())
data = str(data,'utf-8')
8
Shatu

Shatuのpython3に対する回答と似ていますが、少し異なった配置になっています。

import gzip

s = Request("https://someplace.com", None, headers)
r = urlopen(s, None, 180).read()
try: r = gzip.decompress(r)
except OSError: pass
result = json_load(r.decode())

このメソッドを使用すると、gzip.decompress()をtry/exceptでラップして、OSErrorをキャプチャして渡すことができ、圧縮データと非圧縮データが混在する可能性があります。一部の小さな文字列は、エンコードされると実際に大きくなるため、代わりにプレーンデータが送信されます。

2
whitebeard

Requestsモジュールを使用する場合、他のモジュールを使用する必要はありませんgzipおよびdeflatetransfer- encodingsは自動的にデコードされます

例:

>>> import requests
>>> custom_header = {'Accept-Encoding': 'gzip'}
>>> response = requests.get('https://api.github.com/events', headers=custom_header)
>>> response.headers
{'Content-Encoding': 'gzip',...}
>>> response.text
'[{"id":"9134429130","type":"IssuesEvent","actor":{"id":3287933,...

response.textプロパティは、textコンテキストのコンテンツを読み取るためのものです。

response.contentプロパティは、binaryコンテキストのコンテンツを読み取るためのものです。

docs.python-requests.orgBinary Response Content セクションを参照してください

1
simhumileco