我正在用C ++编写一个简单的网络爬虫。
它连接到Web服务器并发送" GET"请求,然后它从Web服务器接收回复。
这是我用来执行此操作的代码:
CHttpHeader reqHeader = websock.GenerateRequestHeader(url, nullptr);
dwResponse = websock.SendRequest(url, reqHeader, nullptr, nullptr);
if (dwResponse == 0) {
//::MessageBoxA(this->GetSafeHwnd(), "error to send http request", 0, 0);
return;
}
//char*strstr = "병맛메로나";
// Receive Response
const int bufferSize = 1024 * 1024 * 1;
char * buffer = new char[bufferSize * 10];
char *tbuffer = new char[bufferSize];
int recvLen = 0;
DWORD dwNextOffset = 0;
//setlocale(LC_ALL, "");
while (websock.HasMoreResponse()) {
recvLen = websock.Recv(tbuffer, bufferSize);
::memcpy(buffer + dwNextOffset, tbuffer, recvLen);
dwNextOffset+= recvLen;
}
服务器回复将被复制到buffer
dwNextOffset
长度。
每件事都可以正常连接到服务器并正确接收回复。但是,在某些情况下使用UTF-8编码的回复,我无法从缓冲区中读取HTML标记。这一切都是胡言乱语。
我想这是由于客户端/服务器操作系统的差异造成的。因为我在Windows上,当Web服务器是IIS(很可能在Windows上运行)时,读取UTF-8编码字符没有问题。但是,在Apache的某些情况下,会出现这个问题。
操作系统之间的UTF-8格式是否不同?
如果是这样,我可以正确转换为MBCS吗?
编辑:这是文件保存部分:
FILE* fp = nullptr;
::fopen_s(&fp, "result", "wb");
::fwrite(buffer, 1, dwOffset, fp);
::fclose(fp);
,结果是..
HTTP/1.1 200 OK Date: Tue, 27 Feb 2018 12:19:19 GMT X-UA-Compatible: IE=10 Expires: Sat, 01, Jan 1970 22:00:00 GMT Pragma: no-cache Cache-Control: no-cache, no-store, must-revalidate P3P: CP="ALL DSP COR MON LAW IVDi HIS IVAi DELi SAMi OUR LEG PHY UNI ONL DEM STA INT NAV PUR FIN OTC GOV" Content-Type: text/html;charset=UTF-8 Content-Language: ko-KR Vary: Accept-Encoding Content-Encoding: gzip X-UA-Device-Type: pc Content-Length: 49043 Connection: close ? 醬??/影?-~퍏뙗*쿭돃?긥먉^...
编辑:Max Vollmer,你是对的。在请求上使用Accept-Encoding : identity
解决了一些问题。但还有另一个问题。
如果我使用此代码:
char *strstr = "병맛메로나";
std::string tstr(strstr);
tstr
正常工作。
但是,如果我将buffer
变为std::string
,则会再次发出乱码。
std::string tstr(buffer);
为什么会这样?
答案 0 :(得分:4)
您的第一个问题,压缩:
-3
您的数据已压缩,您必须将其解压缩。见Content-Encoding。这样做有很多C ++库。
或者,您可以在请求中发送Content-Encoding: gzip
标头,这样服务器就不会发送压缩数据。请参阅Accept-Encoding。
您的第二个问题,编码:
如果缓冲区是UTF-8编码,则不能Accept-Encoding: identity
。首先,它根本不解码任何UTF-8字符。您甚至不会告诉它您的数据是UTF-8编码的,它应该如何知道?其次,任何需要超过8个字节的字符都不能由单个std::string tstr(buffer);
表示,而std :: string使用char
表示其字符,因此char
永远不能保留UTF-8编码数据的文本表示。
您可能会对std::string
实际上是什么感到困惑。 它是一个8位大小的整数。
由于UTF-8使用多个字节对特殊字符进行编码,因此这些字符将存储在char数组中的多个字符中。当您只使用该char数组创建char
时,它只会将每个char解释为一个字符,这是错误的。
您必须将UTF-8数据解码为多字节字符串,例如std::string
,或使用一些第三方库提供一些支持UTF-8开箱即用的字符串类。或者只是将数据写入文件并使用支持UTF-8的文本编辑器打开该文件,它应该自动检测编码。真的取决于你想要做什么。
以下是将UTF-8编码数据转换为std::wstring
的简单方法:
std::wstring