最近查了几天的资料去写一个网页抓取股票实时数据的程序,网上一堆资料都是翻来覆去的讲解同样的方法,还有都是抓取一般的没有变化的对时间要求不要的网页数据,然而对于股票实时数据的抓取要求的是每秒钟都会由很多股票数据在发生变化,要保证程序能抓取到每秒钟这些变化着的数据,好了,出于这个目的开始在网上搜说数据,很多人建议用libcurl方法,好的,libcurl很强大用起来很简单,也想上边说的那样libcurl对于一般的没有变化的网页来说很强大,libcurl达不到每秒钟刷取网页数据10次以上的速度,而且libcurl还会有读取失败延时,而且是延时2~3秒,也就是说在这2~3秒之内网页上变化的数据抓取不到,对于股市来说这就会丢失很大一部分的数据。所以libcurl这个方案被否定了。
可是对于股票这种实时更新对读取次数要求有这么高的,一般的方法都会造成数据的丢失,我能想到做的就是将数据丢失减小到最小范围。我又联想到,为什么浏览器就不会丢失数据呢?可不可以做到像浏览器那样一笔数据都不会丢失呢?(这个问题留在这里带以后解决。)我暂时用的方法就是利用WinInet提供的库函数来开发Internet程序。以下附上代码:
void Get_Http_Data(string Url, string &buffer) { try{ CInternetSession *session = newCInternetSession(); CHttpFile* pfile = (CHttpFile *)session->OpenURL(Url.c_str(),1,INTERNET_FLAG_TRANSFER_ASCII|INTERNET_FLAG_RELOAD|INTERNET_FLAG_DONT_CACHE); if( NULL ==pfile ) { LOG(1)("网络连接中断 或 请求连接失败!"); session->Close(); return; } DWORD dwStatusCode; pfile ->QueryInfoStatusCode(dwStatusCode); if(dwStatusCode ==HTTP_STATUS_OK) { CString data; while (pfile ->ReadString(data)) { if( !data.IsEmpty()) { buffer.append(data.GetBuffer(0)); buffer.append(""); } } } pfile->Close(); delete pfile; session->Close(); } catch(CInternetException *pEx) //这里一定要做异常抛出,考虑到如果程序正在运行中突然客户端网络中断,那么做异常抛出就会即使提示错误并终止。 { //如果不做异常判断的话,程序就会继续运行这样导致buffer为空,记下来的操作万一没有考虑到buffer为空的情况就 pEx->ReportError(); //会导致程序崩溃,因为buffer为空内存无法操作。(比如运行到split函数会崩溃。) pEx->Delete(); } }
利用函数CInternetSession::OpenUrl()来实现对服务器网页的不断请求操作。其中标志:INTERNET_FLAG_RELOAD是强制重复读取网页。
以上程序即方法。其他更优化的方法正在研究中。。。也希望有想法有思路的同仁留下自己的方案。