#include "AFXINET.H"
INT CLOGIN::GetFile(const CString strUrl)//,const CString strSavePath)
{
// AfxMessageBox(strUrl);
unsigned short nPort; //用于保存目标HTTP服务端口
CString strServer, strObject;//strServer用于保存服务器地址,strObject用于保存文件对象名称
DWORD dwServiceType,dwRet; //dwServiceType用于保存服务类型,dwRet用于保存提交GET请求返回的状态号
//解析URL,获取信息
if(!AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort))
{
//解析失败,该Url不正确
return -1;
}
//创建网络连接对象,HTTP连接对象指针和用于该连接的HttpFile文件对象指针,注意delete
CInternetSession intsess;
CHttpFile *pHtFile = NULL;
//建立网络连接
CHttpConnection *pHtCon = intsess.GetHttpConnection(strServer,nPort);
if(pHtCon == NULL)
{
//建立网络连接失败
intsess.Close();
return -2;
}
CString FormDataType = _T("Content-Type:application/x-www-form-urlencoded;charset=UTF-8");
CString m_formdat = _T("TextBox2=1a993111a5&txtUserName=120620223");
//发起GET请求
pHtFile = pHtCon->OpenRequest(CHttpConnection::HTTP_VERB_GET,strObject);
if(pHtFile == NULL)
{
//发起GET请求失败
intsess.Close();
delete pHtCon;
pHtCon = NULL;
return -3;
}
//提交请求头信息
pHtFile->AddRequestHeaders(_T("POST /(gac14yvwcsjrzj45cx1fq4ed)/default2.aspx HTTP/1.1"));
pHtFile->AddRequestHeaders(_T("Accept:text/html, application/xhtml+xml, */*"));
pHtFile->AddRequestHeaders(_T("Accept-Encoding:gzip, deflate"));
pHtFile->AddRequestHeaders(_T("Accept-Language:zh-CN"));
pHtFile->AddRequestHeaders(_T("Cache-Control:no-cache"));
pHtFile->AddRequestHeaders(_T("Connection:Keep-Alive"));
pHtFile->AddRequestHeaders(_T("Content-Length:192"));
pHtFile->AddRequestHeaders(_T("Content-Type:application/x-www-form-urlencoded"));
pHtFile->AddRequestHeaders(_T("Cookie:safedog-flow-item=40A0DA8385864A8908D8E58047659734;"));
pHtFile->AddRequestHeaders(_T("DNT:1"));
pHtFile->AddRequestHeaders(_T("Host:202.200.144.63"));
pHtFile->AddRequestHeaders(_T("Referer:http://202.200.144.63/(gac14yvwcsjrzj45cx1fq4ed)/default2.aspx"));
pHtFile->AddRequestHeaders(_T("User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"));
pHtFile->AddRequestHeaders(_T("ASP.NET_SessionId=hdlg1oi5wz1ibd3ot3omqhr3"));
pHtFile->AddRequestHeaders(_T("X-HttpWatch-RID 74624-10032"));
pHtFile->SendRequest(FormDataType,FormDataType.GetLength(),(LPVOID)(LPCTSTR)m_formdat,m_formdat.GetLength());
//获取服务器返回的状态号
pHtFile->QueryInfoStatusCode(dwRet);
if (dwRet != HTTP_STATUS_OK)
{
//服务器不接受请求
intsess.Close();
delete pHtCon;
pHtCon = NULL;
delete pHtFile;
pHtFile = NULL;
return -4;
}
调试运行的结果是在SendRequest函数出现了异常,报的操作超时
那就先模拟的操作,构造数据,用其他工具直接提交,看是不是可以访问。
我就是在登陆按钮的相应事件中调的GetFile函数,传入的参数是教务处的网址,您说的其他工具是指?
用C++写太麻烦了,直接上python吧!
是在运行期间超时,还是在调试期间超时?
把超时时间设置的长一点试试;
调试期间超时是设置断点跟踪导致的吧。
运行的时候超时……
这里是302,这行数据就是向http服务器发送的post请求吧,我粘出来:http://202.200.144.63/(gac14yvwcsjrzj45cx1fq4ed)/default2.aspx?txtUserName=120620223&TextBox2=1a993111a5 这里边没有对验证码,所以我觉得验证码都是在前端产生的,http服务器根本无需接收验证码的值,所以我自己程序中发post请求不需要管验证码这个吧?
慢慢来,要做这么一个软件,需要了解多方面的知识。
1.首先要了解MFC中和HTTP相关的这些类CInternetSession、CHttpConnection、CHttpFile的用法,可以参考MSDN文档[https://msdn.microsoft.com/zh-cn/library/x4a3bdtx(v=vs.120).aspx]和百度搜到的相关示例代码片段,搞清楚这些类的用法并学会分别发起GET请求和POST请求,我之前贴的那段代码是发起GET请求下载一个文件的,如果要发起POST请求的话,是另外一种用法,显然不是pHtFile->AddRequestHeaders(_T("POST /(gac14yvwcsjrzj45cx1fq4ed)/default2.aspx HTTP/1.1"));就行的。
2.搞清楚这些类的用法以后,还要了解HTTP协议的相关知识。你AddRequestHeaders添加了那么多请求头,他们的含义是什么,哪些应该手工添加,哪些会自动生成,都要了解,像AddRequestHeaders(_T("Content-Length:192"));这样的头是不能手动添加的。除了了解这些头的含义,还要了解Cookie的相关知识,Cookie也不能直接从抓到的包那里复制粘贴过来,要在程序里发起GET请求获取。302重定向该如何处理,都要了解。
3.了解WEB的基本运作原理,然后一开始不要搞这些复杂的教务系统网站,这个正方教务系统不光有验证码,还大量运用的框架,比较复杂。先从一些简单的小网站入手,有的小网站没有验证码,只需一个POST提交账号和密码,不用重定向就能登录成功,先拿简单的小网站练手,尝试GET请求和POST请求,另外还要注意gzip压缩的问题和编码问题,不然获取到的内容都是乱码。
4.小网站搞定以后,开始尝试搞复杂一点的网站,这时还要了解一些HTML和Javascript的知识,大网站POST提交的表单中往往有一些内容,不知道是什么意思,还每次都不一样,比如上面的__VIEWSTATE是什么含义,怎么来的,要通过分析他网页上的javascript代码才能找到答案。有时候打开一个页面,抓包发现了很多请求,这些请求有什么关联,哪些需要模拟发送,哪些不需要,都要研究透彻。
5.获取到返回的HTML内容后,如何从中提取数据,这时候就需要借助一些工具,比如HTML解析器或正则表达式,这些都需要学。
恩恩,谢谢您讲这么多,有点小感动,我会重新把这些知识点弄懂,然后再做,是我自己太浮躁了,总想着只要大概了解那几个函数就能做出来,应该是翻了编程的大忌了……