前一段时间,对一个支持webservice的设备进行数据采集。采用Visual Studio 2015 + Microsoft SQl Server 2008R2,MFC编写。
一、总体思路:
界面:采用MFC对话框。CWebBrowser2控件。(实际运行无界面)
数据存储:根据数据采集要求,指定数据库表。通过类向导MFC ODBC 使用者,建立数据库表类。
数据获取:通过CWebBrowser2控件,访问指定页面,登录以后,进入数据页面,获取数据页面所有框架指针和数量,每个框架下继续查找框架和条目,直至找到对应数据对应的变量。
二、实现过程:
1、数据获取
部分代码如下:
IHTMLDocument2* spDoc2 = (IHTMLDocument2*)m_web.get_Document();;
CString sN_0, sN_1, sN_2, sN_3, sN_4, sN_5, sN_6;
CString sV_0, sV_1, sV_2, sV_3, sV_4, sV_5, sV_6;
IHTMLFramesCollection2* spFramesColl;
//获取总页面的所有Frame指针
spDoc2->get_frames(&spFramesColl);
//获取当前页面中所有Frame的数量
long lCount = 0, lItem = 0;
CComBSTR sContext;
HRESULT hr1 = spFramesColl->get_length(&lCount);
//遍历Frame页面
if (lCount != 0)
{
for (lItem = 0; lItem < lCount; lItem++)
{
CComVariant sResultV;
CComVariant sIndex(lItem);
hr1 = spFramesColl->item(&sIndex, &sResultV);
CComQIPtr<IHTMLWindow2> spWin = sResultV.pdispVal;
//获取第一层Frame页面的指针
CComPtr<IHTMLDocument2> spSubDoc;
hr1 = spWin->get_document(&spSubDoc);
//获取第一层Frame页面的所有元素指针
IHTMLElementCollection *objAllElement2 = NULL;
spSubDoc->get_all(&objAllElement2);
//获取第一层Frame页面所有元素数量
VARIANT name;
long index;
objAllElement2->get_length(&index);
name.vt = VT_I4;
for (long i = 0; i < index; i++)//遍历所有元素,通过id属性获取值
{
name.lVal = i;
IDispatch * pDispatch1 = NULL;
objAllElement2->item(name, name, &pDispatch1);
IHTMLElement* spElement;
pDispatch1->QueryInterface(IID_IHTMLElement, (void**)&spElement);
//通过指定ID查找元素指针,通过元素指针获取指定ID对应的值
CComBSTR tag;
spElement->get_id(&tag);
CString ss(tag);
if (ss == "zoneMainGlobale")//点击事件
{
spElement->click();
}
if (ss == "LIB_GlobalVal1Z")//LIB_SpectrumLib_0
{
spElement->get_outerText(&sContext);
sN_0 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal1ZValue")//LIB_SpectrumValue_0
{
spElement->get_outerText(&sContext);
sV_0 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal2Z")//LIB_SpectrumLib_1
{
spElement->get_outerText(&sContext);
sN_1 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal2ZValue")//LIB_SpectrumValue_1
{
spElement->get_outerText(&sContext);
sV_1 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal3Z")//LIB_SpectrumLib_2
{
spElement->get_outerText(&sContext);
sN_2 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal3ZValue")//LIB_SpectrumValue_2
{
spElement->get_outerText(&sContext);
sV_2 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal4Z")//LIB_SpectrumLib_3
{
spElement->get_outerText(&sContext);
sN_3 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal4ZValue")//LIB_SpectrumValue_3
{
spElement->get_outerText(&sContext);
sV_3 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal5Z")//LIB_SpectrumLib_4
{
spElement->get_outerText(&sContext);
sN_4 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal5ZValue")//LIB_SpectrumValue_4
{
spElement->get_outerText(&sContext);
sV_4 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal6Z")//LIB_SpectrumLib_5
{
spElement->get_outerText(&sContext);
sN_5 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal6ZValue")//LIB_SpectrumValue_5
{
spElement->get_outerText(&sContext);
sV_5 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal7Z")//LIB_SpectrumLib_6
{
spElement->get_outerText(&sContext);
sN_6 = (BSTR)(sContext.m_str);
}
if (ss == "LIB_GlobalVal7ZValue")//LIB_SpectrumValue_6
{
spElement->get_outerText(&sContext);
sV_6 = (BSTR)(sContext.m_str);
}
} if (objAllElement2) { objAllElement2->Release(); }
}
if (spFramesColl) { spFramesColl->Release(); }
}
2、发现问题
问题一:大量的C盘空间被占用
数据采集一分钟执行一次,后台任务方式运行,程序运行不到一个月,C盘多出来50G。
C:\Users\Administrator\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\
产生大量临时页面文件。
问题解决:编写脚本,删除临时文件,设定任务,每天凌晨执行。
问题二:程序崩溃
程序连续运行三四分钟就会出现异常错误,崩溃。
问题解决:在代码中,读取数据并存储到数据库以后,增加关闭程序代码。在任务中,设定启动该程序一分钟一次。
//关闭程序
HANDLE hself = GetCurrentProcess();
TerminateProcess(hself, 0);
三、总结
条条大路通罗马,实现目的是关键。