VS2008 C++ 利用WinHttp API获取任意Http网址的源码

       最近一直在看有关Http的知识,对其基本的理论知识已经有所掌握,想通过一个C++具体的例子进行实际操作。。于是上网查找了很多资料,发现在Windows系统上,可以通过WinHttp API接口开啊Http,于是仿照网上例子编写一个获取网页源码的C++程序。其中的代码基本是copy网友,主要是自己对代码的理解,并以此作为入门。

例子代码如下:

  1 // WinHttpTest.cpp : 定义控制台应用程序的入口点。
  2 //
  3 //#include <stdafx.h>
  4 #include <vector>
  5 #include <winsock2.h>
  6 #include <Winhttp.h>
  7 //#include <urlmon.h>
  8 #include <windows.h>
  9 #include <iostream>
 10 #include <fstream>
 11 #include <string>
 12 #include "AtlBase.h"
 13 #include "AtlConv.h"
 14 using namespace std;
 15 #pragma comment(lib, "winhttp")//这一句不能省略
 16 string GetHost(string strUrl)
 17 {
 18    int indexHttp = strUrl.find("http://");
 19    if(indexHttp != -1)
 20    {
 21        strUrl = strUrl.substr(7);
 22    }
 23    else
 24        return "";
 25    int indexSlash = strUrl.find("/");
 26    if(indexSlash != -1)
 27    {
 28        return strUrl.substr(0, indexSlash);
 29    }
 30    else
 31        return strUrl;
 32    return "";
 33 }
 34 string GetRequestStr(string strUrl)
 35 {
 36    int indexHttp = strUrl.find("http://");
 37    if(indexHttp != -1)
 38    {
 39        strUrl = strUrl.substr(7);
 40    }
 41    else
 42        return "";
 43    int indexSlash = strUrl.find("/");
 44    if(indexSlash == -1)
 45    {
 46        return "";
 47    }
 48    else
 49        return strUrl.substr(indexSlash);
 50 }
 51 string GetHtml(string strUrl)
 52 {
 53    string strHost = GetHost(strUrl);//获取Host
 54    string strRequestStr = GetRequestStr(strUrl);//获取请求路径
 55    USES_CONVERSION;
 56     //2014年7月9日10:02:29
 57     //LPCWSTR的定义 typedef const wchar_t* LPCWSTR;
 58     //LPSTR的定义   typedef char* LPCWSTR;
 59     //LPWSTR的定义  typedef wchar_t* LPWSTR;
 60    LPCWSTR host = A2CW(strHost.c_str());//string转换为常量指针类型
 61    LPCWSTR requestStr = A2CW(strRequestStr.c_str());
 62    //Variables
 63    DWORD dwSize = 0;
 64    DWORD dwDownloaded = 0;
 65    LPSTR pszOutBuffer;
 66    vector <string>  vFileContent;
 67    BOOL  bResults = FALSE;
 68    
 69    //Note the definition of HINTERNET
 70    HINTERNET  hSession = NULL,
 71        hConnect = NULL,
 72        hRequest = NULL;
 73        string strHtml = "";// store the html code
 74        string str;//temporary variables
 75        ofstream out("test.html",ios::binary);//output the html code to a html text;
 76    //2014年7月9日10:39:33
 77    //Search the WinHttp API
 78    //what to do when call the function WinHttpOpen?
 79    // Use WinHttpOpen to obtain a session handle.
 80    hSession = WinHttpOpen(L"WinHTTP Example/1.0",
 81        WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
 82        WINHTTP_NO_PROXY_NAME,
 83        WINHTTP_NO_PROXY_BYPASS, 0);
 84  // Specify an HTTP server.
 85    if (hSession)
 86        hConnect = WinHttpConnect(hSession, host,
 87        INTERNET_DEFAULT_HTTP_PORT, 0);
 88  // Create an HTTP request handle.
 89    if (hConnect)
 90        hRequest = WinHttpOpenRequest(hConnect, L"GET", requestStr,
 91        NULL, WINHTTP_NO_REFERER,
 92        NULL,
 93        NULL);
 94  // Send a request.
 95    if (hRequest)
 96        bResults = WinHttpSendRequest(hRequest,
 97        WINHTTP_NO_ADDITIONAL_HEADERS,
 98        0, WINHTTP_NO_REQUEST_DATA, 0,
 99        0, 0);
100 // End the request.
101    if (bResults)
102        bResults = WinHttpReceiveResponse(hRequest, NULL);
103 
104 //obtain the html source code       
105    if (bResults)
106        do
107        {
108          // Check for available data.
109            dwSize = 0;
110            if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
111                printf( "Error %u in WinHttpQueryDataAvailable.
",
112                GetLastError());
113          // Allocate space for the buffer.
114            pszOutBuffer = new char[dwSize+1];
115            if (!pszOutBuffer)
116            {
117                printf("Out of memory
");
118                dwSize=0;
119            }
120            else
121            {
122                // Read the Data.
123                ZeroMemory(pszOutBuffer, dwSize+1);
124              if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer,
125                    dwSize, &dwDownloaded))
126                {
127                    printf( "Error %u in WinHttpReadData.
",
128                        GetLastError());
129                }
130                else
131                {
132                     //printf("%s", pszOutBuffer);
133                    // Data in vFileContent
134                     vFileContent.push_back(pszOutBuffer);
135                     
136                }
137              // Free the memory allocated to the buffer.
138                delete [] pszOutBuffer;
139            }
140      } while (dwSize>0);
141     // Keep checking for data until there is nothing left.
142    // Report any errors.
143        if (!bResults)
144            printf("Error %d has occurred.
",GetLastError());
145      // Close any open handles.
146        if (hRequest) WinHttpCloseHandle(hRequest);
147        if (hConnect) WinHttpCloseHandle(hConnect);
148        if (hSession) WinHttpCloseHandle(hSession);
149        
150        for(int i=0;i<(int)vFileContent.size();i++)
151        {
152            str=vFileContent[i];
153            out<<str;
154            strHtml += vFileContent[i];
155        }
156        out.close();
157        return strHtml;
158 }
159 int _tmain(int argc, _TCHAR* argv[])
160 {
161 
162    string str = GetHtml("http://bbs.bccn.net/thread-294526-1-1.html");
163    //output the html code
164    //cout << str << endl;
165    system("pause");
166    return 0;
167 }
View Code

 

执行后,可以双击tes.html文件运行,也可打开这个文件与通过浏览器打开的网页源码就行对比。。

原文地址:https://www.cnblogs.com/LCCRNblog/p/3833472.html