使用 curl 时如何正确处理 gzip 页面?

我编写了一个 bash 脚本,它使用 curl 从一个网站获取输出,并对 html 输出进行大量字符串操作。问题在于,当我在一个返回 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

我知道返回的数据是 gzip 压缩的,因为这将如期返回 html:

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

我不希望通过 gunzip 管道输出,因为脚本在其他站点上按原样工作,而通过 gzip 管道输出会破坏该功能。

我已经尽力了

  1. 更改 user-agent (我尝试使用浏览器发送的同一个字符串“ Mozilla/4.0”等)
  2. 男子卷发
  3. 谷歌搜索
  4. 搜索堆栈溢出

一无所获

有什么想法吗?

121977 次浏览

如果设置 --compressed标志,curl将自动解压响应:

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

压缩 (HTTP)使用 libcurl 支持的算法之一请求压缩响应,并保存未压缩的文档。如果使用此选项并且服务器发送不支持的编码,curl 将报告错误。

Gzip 很可能是受支持的,但是您可以通过运行 curl -V并在“ Features”行的某处查找 Libz来检查这一点:

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

请注意,这确实是网站的问题,是在这里的错误。如果 curl没有传递 Accept-Encoding: gzip请求头,服务器就不应该发送压缩响应。

在相关的错误报告 未使用时的原始压缩输出——压缩但服务器返回 gzip 数据 # 2836中,开发人员说:

服务器不应该在客户端没有表示可以接受的情况下发送 content-coding: gzip。

此外,当您不使用—— curl 压缩时,您可以告诉命令行工具您宁愿存储确切的流(压缩或不压缩)。我没看到有卷曲的虫子。

因此,如果服务器可以发送 gzip 内容,使用 --compressed让 curl 自动解压缩它。