如何定制一款12306抢票浏览器――实现自动查询和预定功能(一)

2014-11-24 08:18:56 · 作者: · 浏览: 5
检查是否进入订票页面
判断是否进入订票页面,我是确定了两个标准:
1 网址是否为http://www.12306.cn/mormhweb/kyfw/
2 该页面否有查询按钮
[cpp]
BOOL CDeal12306WebPage::IsQueryPage( CComPtr & spDoc, CComBSTR & bstrUrl )
{
HRESULT hr = E_FAIL;
do {
CString cstrUrl = CString((LPWSTR)bstrUrl);
if ( 0 == cstrUrl.CompareNoCase(LOGIN12306URL) ) {
CComPtr spQueryButton;
hr = GetQueryButtonInQueryPage( spDoc, spQueryButton);
CHECKHRPOINTER(hr, spQueryButton);
}
} while (0);
return FAILED(hr) FALSE : TRUE;
}
URL很好检测,那么我们如何判断是否存在查询按钮呢?我们先看一下订票页面的页面特征。
解决跨域问题
可以见得订票页面内部嵌入了两个Iframe,而我们关心的那块页面恰恰就是最里面一层IFrame。那我们直接通过最外层的Doc获取到最里面的Doc,然后在最里面的Doc执行有关的查询操作即可。然而熟悉java script的同学可能马上就会想到“跨域”问题。其实在 浏览器层面,跨域问题是很好解决的。
[cpp]
HRESULT CDeal12306WebPage::GetIFrameDoc( CComPtr& spDoc,
const CString& cstrIFrameName, CComPtr& spInnerDoc )
{
HRESULT hr = E_FAIL;
do {
CComQIPtr spFrameCollection;
hr = spDoc->get_frames(&spFrameCollection);
CHECKHRPOINTER(hr, spFrameCollection);
CComVariant IframeNameReq = CComBSTR(cstrIFrameName.GetString());
CComVariant FramePage;
hr = spFrameCollection->item(&IframeNameReq, &FramePage);
CHECKHRPOINTER(hr,FramePage.pdispVal);
CComPtr spIFramePage;
hr = FramePage.pdispVal->QueryInterface(IID_IHTMLWindow2, (LPVOID*)&spIFramePage);
CHECKHRPOINTER(hr, spIFramePage);
hr = spIFramePage->
get_document(&spInnerDoc);
if ( E_ACCESSDENIED == hr ) {
CComQIPtr spServiceProvider = spIFramePage;
CHECKPOINT(spServiceProvider);
CComQIPtr spInnerWebBrowser;
hr = spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (LPVOID*)&spInnerWebBrowser);
CHECKHRPOINTER(hr, spInnerWebBrowser);
CComPtr spDisp;
hr = spInnerWebBrowser->get_Document(&spDisp);
CHECKHRPOINTER(hr, spDisp);
hr = spDisp->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&spInnerDoc);
CHECKHRPOINTER(hr, spInnerDoc);
}
} while (0);
return hr;
}
上面这个函数试图在spDoc页面中获取其内嵌的名字是cstrIFrameName的IFrame的Doc。于是我们要获取其中最里面一层Iframe的Doc可以如下调用
[cpp]
HRESULT CDeal12306WebPage::GetIFrameNamedIFramePageDoc( CComPtr & spDoc,
CComPtr & spInnerDoc )
{
HRESULT hr = E_FAIL;
do {
hr = GetIFrameDoc(spDoc, L"iframepage", spInnerDoc);
CHECKHRPOINTER(hr, spInnerDoc);
} while (0);
return hr;
}
HRESULT CDeal12306WebPage::GetIFrameNamedMainDoc( CComPtr & spIFramPageDoc,
CComPtr & spMainDoc )
{
HRESULT hr = E_FAIL;
do {
hr = GetIFrameDoc(spIFramPageDoc, L"main", spMainDoc);
CHECKHRPOINTER(hr, spMainDoc);
} while (0);
return hr;
}
HRESULT CDeal12306WebPage::GetMainDoc( CComPtr & spDoc,
CComPtr & spMainDoc )
{
HRESULT hr = E_FAIL;
do {
CComPtr spIFramePageDoc;
hr = GetIFrameNamedIFramePageDoc(spDoc, spIFramePageDoc);
CHECKHRPOINTER(hr, spIFramePageDoc);
hr = GetIF