www.cctry.com post教程
注意,本文章并非教程
// 在 http://www.idc3389.com/user/modify.asp 源码 // 中找用户数据 CString findUserinfo(CString strElemet,CString strHtmlSrc) { if (strElemet == L"" || strHtmlSrc == L""){ return NULL; } int pos = strHtmlSrc.Find(strElemet); if (pos == -1) { return NULL; } pos = pos + strElemet.GetLength() + 8; // _value=" UINT len = strHtmlSrc.GetLength(); strHtmlSrc = strHtmlSrc.Right(len - pos); pos = strHtmlSrc.Find(L"""); strHtmlSrc = strHtmlSrc.Left(pos); //AfxMessageBox(strHtmlSrc); return strHtmlSrc; }
抓取到的封包
//以下为请求头: POST http://www.idc3389.com/user/userlogin.asp HTTP/1.1 Host: www.idc3389.com Connection: keep-alive Content-Length: 83 Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Origin: http://www.idc3389.com User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 BIDUBrowser/6.x Safari/537.36 Content-Type: application/x-www-form-urlencoded Referer: http://www.idc3389.com/ Accept-Encoding: gzip,deflate Accept-Language: zh-CN,zh;q=0.8 Cookie: pgv_pvid=9485415913; pgv_pvi=1262146560; ASPSESSIONIDAQCTDDQD=NBANEFEBEOFJHGFBANHADDKO; __qc_wId=959; IESESSION=alive; pgv_si=s8099517440 username=username&password=password&screenwidth=&screenheight=&Submit.x=29&Submit.y=12 //以下为应答头: HTTP/1.1 302 Object moved Date: Sun, 12 Oct 2014 14:10:22 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET Location: logininfo.asp Content-Length: 134 Content-Type: text/html Cache-control: private <head><title>Object moved</title></head> <body><h1>Object Moved</h1>This object may be found <a HREF="logininfo.asp">here</a>.</body>
主要代码如下,做了简单注释
/* HTTP1.1协议规定的 HTTP 请求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种。 其中 POST 一般用来向服务端提交数据,本文主要讨论 POST 提交数据的几种方式。 我们知道,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。 规范把 HTTP 请求分为三个部分:状态行、请求头、消息主体。 协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。 实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。 但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python 等,以及它们的 framework, 都内置了自动解析常见数据格式的功能。 服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码, 再对主体进行解析。所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。 */ #import "C:\Windows\syswow64\winhttp.dll" no_namespace void Cidc3389LoginDlg::OnBnClickedButton1() { CString strUserName, strPassword; GetDlgItemText(IDC_EDIT1, strUserName); GetDlgItemText(IDC_EDIT2, strPassword); if (strUserName == L"" || L"" == strPassword){ MessageBox(L"账号或密码不能为空"); return; } CoInitialize(NULL); IWinHttpRequestPtr pHttpReq = NULL; HRESULT hr = pHttpReq.CreateInstance(__uuidof(WinHttpRequest)); if (FAILED(hr)){ CoUninitialize(); } hr = pHttpReq->Open(L"POST", L"http://www.idc3389.com/user/userlogin.asp"); if (FAILED(hr)){ CoUninitialize(); } // 这里注意设置content-type // Content-Type: application/x-www-form-urlencoded pHttpReq->SetRequestHeader(L"Content-Type", L"application/x-www-form-urlencoded"); // 发送POST请求 CString strPost; strPost.Format( L"username=%s&password=%s&screenwidth=&screenheight=&Submit.x=38&Submit.y=14", strUserName, strPassword ); variant_t varPost; varPost = strPost; hr = pHttpReq->Send(varPost); if (FAILED(hr)) { CoUninitialize(); } // // 通过状态码判断登录是否成功; // long status = -1; // pHttpReq->get_Status(&status); // if (status != 200){ // MessageBox(L"登录失败!请检查用户名和密码是否有误!"); // goto _exit0; // } // syc老大的方法, 获取网页元素,判断是否有"欢迎您",这是针对该网站网页源码的。 // 不同网站不同对待 _variant_t varRspBody = pHttpReq->GetResponseBody(); ULONG dataLen = varRspBody.parray->rgsabound[0].cElements; char *pContentBuffer = (char *)varRspBody.parray->pvData; CString strCntBuffer; strCntBuffer = pContentBuffer; CString strSucKey(_T("欢迎您:")); if (strCntBuffer.Find(strSucKey) != -1){ GetDlgItem(IDC_EDIT1)->EnableWindow(FALSE); GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); MessageBox(_T("登陆成功!")); } else { MessageBox(_T("登陆失败!")); } // 登录成功后获取用户信息 hr = pHttpReq->Open(L"GET", L"http://www.idc3389.com/user/modify.asp"); if (FAILED(hr)) { CoUninitialize(); } hr = pHttpReq->Send(); if (FAILED(hr)) { CoUninitialize(); } // 解决乱码问题 varRspBody = pHttpReq->GetResponseBody(); dataLen = varRspBody.parray->rgsabound[0].cElements; pContentBuffer = (char *)varRspBody.parray->pvData; CString strHtmlSrc; strHtmlSrc = pContentBuffer; // 姓名、身份证、EMAIL、TEL CString strElement = L"id="truename""; CString strUserInfo = findUserinfo(strElement, strHtmlSrc); GetDlgItem(EDIT_TRUENAME)->SetWindowTextW(strUserInfo); strElement = L"id="address""; strUserInfo = findUserinfo(strElement, strHtmlSrc); GetDlgItem(EDIT_ADDRESS)->SetWindowTextW(strUserInfo); strElement = L"id="mobi""; strUserInfo = findUserinfo(strElement, strHtmlSrc); GetDlgItem(EDIT_TEL)->SetWindowTextW(strUserInfo); strElement = L"id="email""; strUserInfo = findUserinfo(strElement, strHtmlSrc); GetDlgItem(EDIT_E_MAIL)->SetWindowTextW(strUserInfo); CoUninitialize(); // 关闭的时候再卸载COM组件 }