1

我使用 TIdHttp 来获取网页内容。响应头指示内容编码为 utf8。我想将控制台中的内容打印为 CP936(简体中文),但实际内容不可读。

Result := TEncoding.Utf8.GetString(ResponseBuffer);

我在 python 中做同样的事情(使用 httplib2)没有任何问题。

def python_try():
    conn = httplib2.HttpConn()
    respose, content = conn.get(...)
    print content.decode('utf8') # readable in console

更新 1

我调试了原始响应并注意到内容被压缩了。

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Content-Encoding: gzip
Vary: Accept-Encoding
Date: Mon, 24 Dec 2012 15:27:44 GMT
Connection: Keep-Alive

我试图将 IdCompressorZLib 实例分配给 IdHttp 实例。不幸的是,应用程序在解压缩 gzip 内容时会崩溃。测试地址为“http\://www.baidu.com”(编码=gb2312)。


更新 2

我还尝试下载一个 gzipped jquery 脚本文件,它只包含 ascii 字符。这次成功了,这意味着是Indy库的问题。如果我没有错,我应该关闭这个问题。

4

2 回答 2

2

TIdHTTP如果您有一个TIdCompressorZLib组件分配给该TIdHTTP.Compressor属性,则为您处理 gzip 解压缩。否则,您将不得不手动解压缩它(如果未分配该属性,则默认情况下TIdHTTP不会发送标头)。Accept-EncodingCompressor

至于 UTF-8 编码,如果您正在调用返回值而不是填充对象的or方法TIdHTTP的重载版本,也可以为您处理。它将为您将 UTF-8 解码为 UTF-16。要将其转换为 CP936,您可以让 RTL 为您进行转换:TIdHTTP.Get()TIdHTTP.Post()StringTStream

type
  Cp936String = type AnsiString(936);
var
  S: Cp936String;
begin
  S := Cp936String(IdHTTP1.Get(...));
于 2012-12-25T01:00:21.353 回答
1

不要使用任何自动检测编码,它不能可靠地完成。只需相信 Content-Type 标头即可。

Result := TEncoding.Utf8.GetString(ResponseBuffer);

如果 Content-Type 标头丢失或撒谎,则需要检测编码。虽然我不会使用任何将 UTF-8 误检测为 CP936 的算法......

于 2012-12-24T06:58:04.250 回答