web-dev-qa-db-ja.com

curlを使用するときにgzip圧縮されたページを適切に処理する方法は?

Curlを使用してWebサイトから出力を取得し、html出力に対して一連の文字列操作を行うbashスクリプトを作成しました。問題は、gzipで圧縮された出力を返すサイトに対して実行した場合です。ブラウザでサイトにアクセスしても問題ありません。

手でcurlを実行すると、gzip圧縮された出力が得られます。

$ curl "http://example.com"

その特定のサイトのヘッダーは次のとおりです。

HTTP/1.1 200 OK
Server: nginx
Content-Type: text/html; charset=utf-8
X-Powered-By: PHP/5.2.17
Last-Modified: Sat, 03 Dec 2011 00:07:57 GMT
ETag: "6c38e1154f32dbd9ba211db8ad189b27"
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: must-revalidate
Content-Encoding: gzip
Content-Length: 7796
Date: Sat, 03 Dec 2011 00:46:22 GMT
X-Varnish: 1509870407 1509810501
Age: 504
Via: 1.1 varnish
Connection: keep-alive
X-Cache-Svr: p2137050.pubip.peer1.net
X-Cache: HIT
X-Cache-Hits: 425

期待どおりhtmlを返すため、返されたデータはgzipで圧縮されていることがわかります。

$ curl "http://example.com" | gunzip

スクリプトが他のサイトでそのまま動作し、gzipを介してパイピングするとその機能が壊れるので、gunzipを介して出力をパイピングしたくありません。

私が試したこと

  1. ユーザーエージェントの変更(ブラウザが送信するのと同じ文字列 "Mozilla/4.0"などを試しました)
  2. 男カール
  3. グーグル検索
  4. スタックオーバーフローの検索

すべてが空になりました

何か案は?

116
BryanH

curlは、--compressedフラグを設定すると、応答を自動的に解凍します。

curl --compressed "http://example.com"

-compressed(HTTP)libcurlがサポートするアルゴリズムの1つを使用して圧縮された応答を要求し、圧縮されていないドキュメントを保存します。このオプションが使用され、サーバーがサポートされていないエンコードを送信すると、curlはエラーを報告します。

gzipがサポートされている可能性が高いですが、curl -Vを実行し、「機能」行のどこかでlibzを探すことでこれを確認できます。

$ curl -V
...
Protocols: ...
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz 

ここで問題になっているのは、実際に問題のWebサイトであることに注意してください。 curlAccept-Encoding: gzip要求ヘッダーを渡さなかった場合、サーバーは圧縮された応答を送信してはなりません。

230
Martin