首页 > 代码库 > MFC抓取网页代码。

MFC抓取网页代码。

本人是初学MFC,这几天都要弄怎么抓取网页代码,一开始是一头雾水,不过最后多亏网上的丰富资源,让我有所收获,我也帮助新手们,下面是我自己参考网上资料所得的。

 1 #pragma once 2  3  4 //抓取网页代码封装类 5  6 #include <afxinet.h> //所需要的函数的头文件。 7  8  9 class CGetInternet10 {11 public:12     CGetInternet();13     virtual ~CGetInternet();14 15     //添加变量16 protected:17     CString        m_strError;  //接受错误信息18     CString        m_HttpCode;  //接受抓取的网页代码19     UINT           PageCode;   //CP_UTF8:65001 CP_ACP:0  转换代码用  20 21     //添加自定义函数22 public:23     BOOL OnInitSession(CInternetSession &session);//判断链接是否成功。可以不要24     25     CString GetHttpCode(CString &url); //主要接口,输入网址,获取代码26     27     int OnProcessError(int dwRetcode, CInternetSession &session,28                 CHttpConnection *pServer, CHttpFile *pFile);//链接错误函数29 30 31 };
  1 #include "stdafx.h"  2 #include "GetInternet.h"  3   4 //验证的字符串  5 const TCHAR szHeaders[] = _T("Accept: _T/*\r\nUser-Agent: LCD‘s Infobay Http Client\r\n");  6   7 //构造函数  8 CGetInternet::CGetInternet()  9 { 10     PageCode = 65001; //因为我们的网址是UTF8格式,所以用65001; 11     m_HttpCode = _T(""); 12 } 13  14 //析构函数 15 CGetInternet::~CGetInternet() 16 { 17     m_strError.ReleaseBuffer(); 18 } 19  20 //主要接口,输入网址,获取代码 21 CString CGetInternet::GetHttpCode(CString &url) 22 { 23     //获取网页的初始化工作 24     CInternetSession session(NULL, 0);  25     CHttpFile *htmlFile = NULL; 26     TCHAR sRecv[1024];  //接受缓存代码。 27  28     //错误判断初始化 29     DWORD dwServiceType = 0; 30     DWORD  dwHttpRequestFlags = INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_AUTO_REDIRECT; 31     CString strServerName = _T(""); 32     CString strObject = _T(""); 33     INTERNET_PORT nPort = 0; 34     CString StrContent = _T(""); 35     DWORD dwRetcode = -1; 36  37     CHttpConnection *pServer = NULL; 38  39     try 40     { 41         if (!OnInitSession(session)) //判断链接是否成功;可以不要 42         { 43             return NULL; 44         } 45         if (!AfxParseURL(url, dwServiceType, strServerName, strObject, nPort) || dwServiceType != INTERNET_SERVICE_HTTP) 46         { 47             m_strError = _T("非法的URL"); 48             return NULL; 49         } 50  51         pServer = session.GetHttpConnection(strServerName, nPort); 52  53  54         if (pServer == NULL) 55         { 56             m_strError = _T("无法与服务器建立连接"); 57             return NULL; 58         } 59         //下面第一个可以为1  打开http链接 60         htmlFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject, 61             NULL, 1, NULL, NULL, dwHttpRequestFlags); 62  63         if (htmlFile == NULL) 64         { 65             m_strError = _T("无法与服务器建立连接"); 66             return NULL; 67         } 68  69         ///////////////////////////////////////////////// 70         try 71         { //调用此成员函数添加一个或多个HTTP请求标头到HTTP请求处理。AddRequestHeaders 72             // 73             if (!htmlFile->AddRequestHeaders(szHeaders) || !htmlFile->SendRequest()) 74             { 75                 m_strError = _T("网络错误-无法发送请求报头"); 76                 return NULL; 77             } 78         } 79         catch (CInternetException *ex) 80         { 81             StrContent.Empty(); 82             m_strError = _T("无法发送http报头,可能网络状况有问题"); 83             ex->Delete(); 84             return NULL; 85         } 86         ////////////////////////////////////////////////////////////////////////// 87  88         if (!htmlFile->QueryInfoStatusCode(dwRetcode)) 89         { 90             m_strError = _T("网络错误-无法查询反馈代码"); 91             return NULL; 92         } 93  94         if (dwRetcode >= 200 && dwRetcode < 300) 95         { 96             try 97             { 98                 //htmlFile = (CHttpFile*)session.OpenURL(url);//打开链接 99 100                 while (htmlFile->ReadString(sRecv, 1024))101                 {102                     // 编码转换,可解决中文乱码问题  103                     //gb2312转为unicode,则用CP_ACP  104                     //gbk转为unicode,也用CP_ACP  105                     //utf-8转为unicode,则用CP_UTF8  106                     int nBufferSize = MultiByteToWideChar(PageCode, 0, (LPCSTR)sRecv, -1, NULL, 0);107 108                     wchar_t *pBuffer = new wchar_t[nBufferSize + 1];109                     memset(pBuffer, 0, (nBufferSize + 1) *sizeof(wchar_t));110 111                     //gb2312转为unicode,则用CP_ACP  112                     //gbk转为unicode,也用CP_ACP  113                     //utf-8转为unicode,则用CP_UTF8  114                     MultiByteToWideChar(PageCode, 0, (LPCSTR)sRecv, -1, pBuffer, nBufferSize *sizeof(wchar_t));115 116                     m_HttpCode += pBuffer;117                     m_HttpCode += "\r\n";118                     delete pBuffer;119                 }120 121                 htmlFile->Close();122                 session.Close();123                 delete htmlFile;124                 125                 //多余。126                 CFile file;127                 file.Open(_T("test2.txt"), CFile::modeCreate | CFile::modeNoTruncate | CFile::modeReadWrite);128                 file.Write(m_HttpCode, m_HttpCode.GetLength());129                 file.Close();130                 131                 return m_HttpCode;132 133             }134             catch (CInternetException* pEx)135             {136                 m_strError = _T("接收数据错误");137                 pEx->Delete();138 139                 //因为是CString,所以返回NULL,而不是0;140                 return NULL;141             }142             return StrContent;143 144         }145         else146         {147             //读取失败,将buffer清空。148             StrContent.Empty();149 150             //发送错误。151             OnProcessError(dwRetcode, session, pServer, htmlFile);152 153             return NULL;154         }155 156     }157     catch (CInternetException* pEx)158     {159         m_strError = _T("网络错误");160 161         pEx->Delete();162         return NULL;163     }164 165     return NULL;166 }167 168 169 //判断链接是否成功。可以不要170 BOOL CGetInternet::OnInitSession(CInternetSession &session)171 {172     //超时设置很重要!如果设置太小回引起服务器超时,如果设置太大则回引起线程挂起。173     //在重试连接之间的等待的延时值在毫秒级。174     //网络连接请求时间超时值在数毫秒级。如果连接请求时间超过这个超时值,请求将被取消。缺省的超时值是无限的。175     //在网络连接请求时的重试次数。如果一个连接企图在指定的重试次数后仍失败,则请求被取消。缺省值为5。176     try177     {178         if (!session.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 10000) ||  //超时179             !session.SetOption(INTERNET_OPTION_CONNECT_BACKOFF, 1000) ||    //延迟180             !session.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 3) ||       //重试181             !session.SetOption(INTERNET_OPTION_RECEIVE_TIMEOUT, 60000) ||       //最大超时182             !session.EnableStatusCallback(TRUE))            //建立一个状态回调例程。异步操作需要183         {184             return FALSE;185         }186         else187         {188             return TRUE;189         }190     }191     catch (CInternetException* pEx)192     {193         pEx->GetErrorMessage(m_strError.GetBuffer(0), 1023);194         pEx->Delete();195 196         return FALSE;197     }198 199 }200 201 //链接错误函数202 int CGetInternet::OnProcessError(int dwRetcode, CInternetSession &session,203     CHttpConnection *pServer, CHttpFile *pFile)204 {205     switch (dwRetcode)206     {207     case 100:208         m_strError = _T("客户方错误-继续 [Continue]");209         break;210         //211     case 101:212         m_strError = _T("客户方错误-交换协议 [witching Protocols]");213         break;214         //215     case 204:216         m_strError = _T("网页内容为空 [No Content]");217         break;218         //------------------------------------------------------------219     case 400:220         m_strError = _T("错误请求 [Bad Request]");221         break;222         //223     case 401:224         m_strError = _T("网页需要验证信息 [Unauthorized]");225         break;226         //227     case 402:228         m_strError = _T("网页需要付费 [Payment Required]");229         break;230         //231     case 403:232         m_strError = _T("禁止访问 [Forbidden]");233         break;234         //235     case 404://236         m_strError = _T("没有找到网页 [Not Found]");237         break;238         //239     case 405:240         m_strError = _T("不允许Http访问该文件 [Method Not Allowed]");241         break;242         //243     case 406:244         m_strError = _T("该文件不允许访问 [Not Acceptable]");245         break;246         //247     case 407:248         m_strError = _T("该文件需要代理认证 [Proxy Authentication Required]");249         break;250         //251     case 408:252         m_strError = _T("对该文件请求超时 [Request Time-out]");253         break;254         //255     case 409:256         m_strError = _T("对该文件访问冲突 [Conflict]");257         break;258         //259     case 410:260         m_strError = _T("对该文件访问失败 [Gone]");261         break;262         //263     case 411:264         m_strError = _T("该文件需要长度信息 [Length Required]");265         break;266         //267     case 412:268         m_strError = _T("请求条件失败 [Precondition Failed]");269         break;270         //271     case 413:272         m_strError = _T("请求文件实体太大 [Request Entity Too Large]");273         break;274         //275     case 414:276         m_strError = _T("请求的URI太长 [Request-URI Too Large]");277         break;278         //279     case 415:280         m_strError = _T("不支持媒体类型 [Unsupported Media Type]");281         break;282         //283     case 416:284         m_strError = _T("队列请求失败 [Requested range not satisfiable]");285         break;286         //287     case 417:288         m_strError = _T("预期失败 [Expectation Failed]");289         break;290         //--------------------------------------------------------------291     case 500:292         m_strError = _T("服务器内部错误 [Internal Server Error]");293         break;294         //295     case 501:296         m_strError = _T("未实现请求 [Not Implemented]");297         break;298         //299     case 502:300         m_strError = _T("网关失败 [Bad Gateway]");301         break;302         //303     case 503:304         m_strError = _T("没有找到服务器 [Service Unavailable]");305         break;306         //307     case 504:308         m_strError = _T("网关超时 [Gateway Time-out]");309         break;310         //311     case 505:312         m_strError = _T("服务器不支持系统使用的HTTP版本 [HTTP Version not supported]");313         break;314         //315     }316 317     try318     {319         if (pFile != NULL) SafeDelete(pFile);320         if (pServer != NULL) SafeDelete(pServer);321 322         session.Close();323 324         return 0;325     }326     catch (CInternetException *pEx)327     {328         pEx->GetErrorMessage(m_strError.GetBuffer(0), 1024);329         pEx->Delete();330 331         return 0;332     }333 }

 

 


//多余。
CFile file;
file.Open(_T("test2.txt"), CFile::modeCreate | CFile::modeNoTruncate | CFile::modeReadWrite);
file.Write(m_HttpCode, m_HttpCode.GetLength());
file.Close();

 

这个是用来查看抓取的代码。

 

PS:

 

需要在stdafx.h加入这个

//删除指针
#define SafeDelete(pData) { try { delete pData; } catch (...) { ASSERT(FALSE); } pData=http://www.mamicode.com/NULL; }

 

1,创建一个MFC的基本对话框,

2.创建一个c++类,将上面代码加入,

3.在OnInitDialog函数中调用:

// TODO: 在此添加额外的初始化代码

CGetInternet get1;
CString url = _T("http://www.tqyb.com.cn/index.html");
get1.GetHttpCode(url);

 

以上。

 

感谢:

http://code.it168.com/v/yigecongwangyetaglimianfenxiurlheurlbiaotideleivcyuandaima/GetWeb.cpp

http://blog.chinaunix.net/uid-27213819-id-3781188.html

http://www.gymsaga.com/project/728.html

 

感谢这三位博主的开源。