|
|
【程序】C++使用WinHttp发送HTTP请求,然后用MSXML6解析从服务器获得的XML内容 |
一派护法 十九级 |
【功能】 调用Arslanbar2.0 API获取并显示最新的25个主题帖的标题。 【程序运行结果】
|
一派护法 十九级 |
【C++代码】 // HTTP.cpp : 定义控制台应用程序的入口点。 //
#include "stdafx.h" #include <iostream> #include <sstream>
#include <comutil.h> #include <MsXml6.h> #include <Windows.h> #include <Winhttp.h>
#pragma comment(lib, "comsuppw.lib") #pragma comment(lib, "msxml6.lib") #pragma comment(lib, "Winhttp.lib")
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); IXMLDOMDocument *pXMLDoc; CoCreateInstance(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pXMLDoc));
HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, NULL); if (hSession) { HINTERNET hConnect = WinHttpConnect(hSession, L"zh.arslanbar.net", INTERNET_DEFAULT_HTTP_PORT, NULL); HINTERNET hRequest = WinHttpOpenRequest(hConnect, NULL, L"API?variant=zh-cn&query=posts", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH); WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, WINHTTP_NO_REQUEST_DATA, NULL, NULL, NULL);
BOOL bResult = WinHttpReceiveResponse(hRequest, NULL); if (bResult) { // 获取网页内容,以UTF-8编码存储到stream中 DWORD dwRead = 0; DWORD dwSize; stringstream stream; while (WinHttpQueryDataAvailable(hRequest, &dwSize), dwSize > 0) { char *buffer = new char[dwSize]; WinHttpReadData(hRequest, buffer, dwSize, &dwRead); stream.write(buffer, dwSize); delete[] buffer; }
// 将UTF-8转换为UTF-16,再转换为BSTR string data = stream.str(); stream.clear(); dwSize = MultiByteToWideChar(CP_UTF8, NULL, data.c_str(), -1, NULL, NULL); LPWSTR w_data = new WCHAR[dwSize]; MultiByteToWideChar(CP_UTF8, NULL, data.c_str(), -1, w_data, dwSize); data.clear(); BSTR b_data = SysAllocString(w_data); delete[] w_data;
// 用MSXML6解析XML字符串 VARIANT_BOOL flag; pXMLDoc->loadXML(b_data, &flag); SysFreeString(b_data); if (flag == VARIANT_TRUE) { // 解析成功 IXMLDOMElement *root; IXMLDOMNodeList *children; long i, length; pXMLDoc->get_documentElement(&root); root->get_childNodes(&children); children->get_length(&length); cout << "共有" << length - 1 << "个主题: " << endl; for (i = 1; i < length; i++) { IXMLDOMNode *post_node; IXMLDOMNode *title_node; BSTR b_title; children->get_item(i, &post_node); post_node->get_firstChild(&title_node); title_node->get_text(&b_title); string title = bstr_t(b_title); cout << title << endl; SysFreeString(b_title);
title_node->Release(); post_node->Release(); }
children->Release(); root->Release(); } else cout << "解析XML字符串失败" << endl; }
WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); } else cout << "Error " << GetLastError() << " in WinHttpOpen." << endl;
WinHttpCloseHandle(hSession); pXMLDoc->Release(); CoUninitialize(); std::system("pause"); return 0; }
|
一派护法 十九级 |
【C++代码2:不使用bstr_t类】 // HTTP.cpp : 定义控制台应用程序的入口点。 //
#include "stdafx.h" #include <iostream> #include <sstream>
#include <comutil.h> #include <MsXml6.h> #include <Windows.h> #include <Winhttp.h>
#pragma comment(lib, "comsuppw.lib") #pragma comment(lib, "msxml6.lib") #pragma comment(lib, "Winhttp.lib")
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); IXMLDOMDocument *pXMLDoc; CoCreateInstance(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pXMLDoc));
HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, NULL); if (hSession) { HINTERNET hConnect = WinHttpConnect(hSession, L"zh.arslanbar.net", INTERNET_DEFAULT_HTTP_PORT, NULL); HINTERNET hRequest = WinHttpOpenRequest(hConnect, NULL, L"API?variant=zh-cn&query=posts", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_REFRESH); WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, WINHTTP_NO_REQUEST_DATA, NULL, NULL, NULL);
BOOL bResult = WinHttpReceiveResponse(hRequest, NULL); if (bResult) { // 获取网页内容,以UTF-8编码存储到stream中 DWORD dwRead = 0; DWORD dwSize; stringstream stream; while (WinHttpQueryDataAvailable(hRequest, &dwSize), dwSize > 0) { char *buffer = new char[dwSize]; WinHttpReadData(hRequest, buffer, dwSize, &dwRead); stream.write(buffer, dwSize); delete[] buffer; }
// 将UTF-8转换为UTF-16,再转换为BSTR string data = stream.str(); stream.clear(); dwSize = MultiByteToWideChar(CP_UTF8, NULL, data.c_str(), -1, NULL, NULL); LPWSTR w_data = new WCHAR[dwSize]; MultiByteToWideChar(CP_UTF8, NULL, data.c_str(), -1, w_data, dwSize); data.clear(); BSTR b_data = SysAllocString(w_data); delete[] w_data;
// 用MSXML6解析XML字符串 VARIANT_BOOL flag; pXMLDoc->loadXML(b_data, &flag); SysFreeString(b_data); if (flag == VARIANT_TRUE) { // 解析成功 IXMLDOMElement *root; IXMLDOMNodeList *children; long i, length; pXMLDoc->get_documentElement(&root); root->get_childNodes(&children); children->get_length(&length); cout << "共有" << length - 1 << "个主题: " << endl; for (i = 1; i < length; i++) { IXMLDOMNode *post_node; IXMLDOMNode *title_node; BSTR b_title; children->get_item(i, &post_node); post_node->get_firstChild(&title_node); title_node->get_text(&b_title); char *title = _com_util::ConvertBSTRToString(b_title); cout << title << endl; delete[] title; SysFreeString(b_title);
title_node->Release(); post_node->Release(); }
children->Release(); root->Release(); } else cout << "解析XML字符串失败" << endl; }
WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); } else cout << "Error " << GetLastError() << " in WinHttpOpen." << endl;
WinHttpCloseHandle(hSession); pXMLDoc->Release(); CoUninitialize(); std::system("pause"); return 0; }
|
|
|
|