当前位置: 首页 > 编程日记 > 正文

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

检查是否进入订票页面

判断是否进入订票页面,我是确定了两个标准:(转载请指明出于breaksoftware的csdn博客)

1 网址是否为http://www.12306.cn/mormhweb/kyfw/

2 该页面否有查询按钮

BOOL CDeal12306WebPage::IsQueryPage( CComPtr<IHTMLDocument2> & spDoc, CComBSTR & bstrUrl )
{HRESULT hr = E_FAIL;do  {CString cstrUrl = CString((LPWSTR)bstrUrl);if ( 0 == cstrUrl.CompareNoCase(LOGIN12306URL) ) {CComPtr<IHTMLElement> spQueryButton;hr = GetQueryButtonInQueryPage( spDoc, spQueryButton);CHECKHRPOINTER(hr, spQueryButton);}} while (0);return FAILED(hr) ? FALSE : TRUE;
}
URL很好检测,那么我们如何判断是否存在查询按钮呢?我们先看一下订票页面的页面特征。


解决跨域问题

可以见得订票页面内部嵌入了两个Iframe,而我们关心的那块页面恰恰就是最里面一层IFrame。那我们直接通过最外层的Doc获取到最里面的Doc,然后在最里面的Doc执行有关的查询操作即可。然而熟悉javascript的同学可能马上就会想到“跨域”问题。其实在浏览器层面,跨域问题是很好解决的。

HRESULT CDeal12306WebPage::GetIFrameDoc( CComPtr<IHTMLDocument2>& spDoc, const CString& cstrIFrameName, CComPtr<IHTMLDocument2>& spInnerDoc )
{HRESULT hr = E_FAIL;do {CComQIPtr<IHTMLFramesCollection2> 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<IHTMLWindow2> spIFramePage;hr = FramePage.pdispVal->QueryInterface(IID_IHTMLWindow2, (LPVOID*)&spIFramePage);CHECKHRPOINTER(hr, spIFramePage);hr = spIFramePage->get_document(&spInnerDoc);if ( E_ACCESSDENIED == hr ) {CComQIPtr<IServiceProvider> spServiceProvider = spIFramePage;CHECKPOINT(spServiceProvider);CComQIPtr<IWebBrowser2> spInnerWebBrowser;hr = spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (LPVOID*)&spInnerWebBrowser);CHECKHRPOINTER(hr, spInnerWebBrowser);CComPtr<IDispatch> 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可以如下调用

HRESULT CDeal12306WebPage::GetIFrameNamedIFramePageDoc( CComPtr<IHTMLDocument2> & spDoc, CComPtr<IHTMLDocument2> & spInnerDoc )
{HRESULT hr = E_FAIL;do {hr =  GetIFrameDoc(spDoc, L"iframepage", spInnerDoc);CHECKHRPOINTER(hr, spInnerDoc);} while (0);return hr;
}HRESULT CDeal12306WebPage::GetIFrameNamedMainDoc( CComPtr<IHTMLDocument2> & spIFramPageDoc,CComPtr<IHTMLDocument2> & spMainDoc )
{HRESULT hr = E_FAIL;do {hr =  GetIFrameDoc(spIFramPageDoc, L"main", spMainDoc);CHECKHRPOINTER(hr, spMainDoc);} while (0);return hr;
}HRESULT CDeal12306WebPage::GetMainDoc( CComPtr<IHTMLDocument2> & spDoc,CComPtr<IHTMLDocument2> & spMainDoc )
{HRESULT hr = E_FAIL;do {CComPtr<IHTMLDocument2> spIFramePageDoc;hr = GetIFrameNamedIFramePageDoc(spDoc, spIFramePageDoc);CHECKHRPOINTER(hr, spIFramePageDoc);hr = GetIFrameNamedMainDoc(spIFramePageDoc, spMainDoc);CHECKHRPOINTER(hr, spMainDoc);} while (0);return hr;
}
当我们获得最里层的Doc后,我们将根据页面结构获取Class为cx_from的Table元素。


          获取这个Table的原因是,之后我们会以该Table为节点,执行“查询按钮”查找的操作。

HRESULT CDeal12306WebPage::GetQueryButtonInQueryPage( CComPtr<IHTMLDocument2> & spDoc, CComPtr<IHTMLElement> & spQueryButtonElem )
{HRESULT hr = E_FAIL;do  {CComPtr<IHTMLDocument2> spMainDoc;hr = GetMainDoc( spDoc, spMainDoc);CHECKHRPOINTER(hr, spMainDoc);CComPtr<IHTMLElement> spEnter_wElem;hr = GetEnter_wElement(spMainDoc, spEnter_wElem );CHECKHRPOINTER(hr, spEnter_wElem);CComPtr<IHTMLElement> spQueryTable;hr = GetQueryTable(spEnter_wElem, spQueryTable);CHECKHRPOINTER(hr, spQueryTable);CComPtr<IHTMLButtonElement> spQueryButton;hr = GetQueryButtonInQueryPage(spQueryTable, spQueryButton);CHECKHRPOINTER(hr, spQueryButton);hr = spQueryButton->QueryInterface(IID_IHTMLElement, (LPVOID*)& spQueryButtonElem);CHECKHRPOINTER(hr, spQueryButtonElem);} while (0);return hr;
}
查询按钮在这个table中的位置是



        于是通过该Table查询”查询“按钮的代码是

HRESULT CDeal12306WebPage::GetQueryButtonInQueryPage( CComPtr<IHTMLElement>& spQueryTable, CComPtr<IHTMLButtonElement> & spQueryButton )
{HRESULT hr = E_FAIL;do {CComPtr<IHTMLElement> spTBody;hr = GetElementByIndex(spQueryTable, 0, spTBody);CHECKHRPOINTER(hr, spTBody);CComPtr<IHTMLElement> spFirstTR;hr = GetElementByIndex(spTBody, 0, spFirstTR);CHECKHRPOINTER(hr, spFirstTR);CComPtr<IHTMLElement> spEighthTR;hr = GetElementByIndex(spFirstTR, 8, spEighthTR);CHECKHRPOINTER(hr, spEighthTR);CComPtr<IHTMLElement> spButtonTemp;hr = GetElementByIndex(spEighthTR, 0, spButtonTemp);CHECKHRPOINTER(hr, spButtonTemp);hr = spButtonTemp->QueryInterface(IID_IHTMLButtonElement, (LPVOID*)&spQueryButton);CHECKHRPOINTER(hr, spQueryButton);} while (0);return hr;
}
插入开始和停止自动查询按钮
为了在该页面中提供给用于控制开启和关闭自动查询功能的按钮,我插入了两个按钮。如下图


我们看下”单程“和”返程“按钮的页面结构


我会在Name为querySingleForm的form下的class为cx_tab的Div下插入“开始”和“停止”按钮。

HRESULT CDeal12306WebPage::InsertButtonInQueryPage( CComPtr<IHTMLDocument2> & spDoc )
{HRESULT hr = E_FAIL;do  {CComPtr<IHTMLDocument2> spMainDoc;hr = GetMainDoc( spDoc, spMainDoc);CHECKHRPOINTER(hr, spMainDoc);CComPtr<IHTMLElement> spEnter_wElem;hr = GetEnter_wElement(spMainDoc, spEnter_wElem );CHECKHRPOINTER(hr, spEnter_wElem);CComPtr<IHTMLElement> spForm;hr = GetQuerySingleForm(spEnter_wElem, spForm);CHECKHRPOINTER(hr, spForm);hr = InsertButtons( spForm );} while (0);return hr;
}
HRESULT CDeal12306WebPage::InsertButtons(CComPtr<IHTMLElement> & spEnter_wElem )
{HRESULT hr = E_FAIL;do {CComPtr<IHTMLElement> spDiv;hr  = GetInsertButtonElem(spEnter_wElem, spDiv);if (  FALSE == IsStartButtonExist(spDiv) ) {hr = InsertStartButton(spDiv);CHECKHR(hr);
#ifdef DEBUGif ( FALSE == IsStartButtonExist(spDiv) ) {DebugBreak();}
#endif}if ( FALSE == IsStopButtonExist(spDiv) ) {hr = InsertStopButton(spDiv);CHECKHR(hr);
#ifdef DEBUGif ( FALSE == IsStopButtonExist(spDiv) ) {DebugBreak();}
#endif}} while (0);return hr ;
}
HRESULT CDeal12306WebPage::GetInsertButtonElem( CComPtr<IHTMLElement> & spForm, CComPtr<IHTMLElement> & spDiv )
{HRESULT hr = E_FAIL;do {CComPtr<IHTMLElement> spCx_TabDiv;hr = GetElementByClassName(spForm, L"cx_tab", spCx_TabDiv);CHECKHRPOINTER(hr, spCx_TabDiv);hr = GetElementByIndex(spCx_TabDiv, 0, spDiv);CHECKHRPOINTER(hr, spDiv);} while (0);return hr;
}HRESULT CDeal12306WebPage::InsertStartButton( CComPtr<IHTMLElement> & spElem )
{HRESULT hr = E_FAIL;do {CComBSTR bstrWhere(L"beforeEnd");CString cstrHTML;cstrHTML.Format( BUTTONFORMAT, STARTBUTTONID, STARTCOMD, L"开始" );CComBSTR bstrHTML(cstrHTML.GetString());hr = spElem->insertAdjacentHTML( bstrWhere, bstrHTML );CHECKHR(hr);} while (0);return hr ;
}HRESULT CDeal12306WebPage::InsertStopButton( CComPtr<IHTMLElement> & spElem )
{HRESULT hr = E_FAIL;do {CComBSTR bstrWhere(L"beforeEnd");CString cstrHTML;cstrHTML.Format( BUTTONFORMAT, STOPBUTTONID, STOPCMD, L"停止" );CComBSTR bstrHTML(cstrHTML.GetString());hr = spElem->insertAdjacentHTML( bstrWhere, bstrHTML );CHECKHR(hr);} while (0);return hr ;
}
#define BUTTONFORMAT    L"<li id=\"%s\"><a href=\"%s\" style=\"width:50px;height:30px;\">%s</a></li>"
#define STARTBUTTONID   L"StartButton"
#define STOPBUTTONID    L"StopButton"
#define STARTCOMD       L"http://www.12306.cn/mormhweb/kyfw/StartQuery.fl"
#define STOPCMD         L"http://www.12306.cn/mormhweb/kyfw/StopQuery.fl"
当我们点击开始按钮是,页面将试图跳转到http://www.12306.cn/mormhweb/kyfw/StartQuery.fl,此时,我将终止该跳转,同时将“开启查询”标志设置为TRUE。

void CBrowserHost::BeforeNavigate2(IDispatch *pDisp, VARIANT *url,VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData,VARIANT *Headers, VARIANT_BOOL *Cancel)
{do  {if ( NULL != url ) {CString cstrUrl((LPWSTR)(url->bstrVal));if ( 0 == cstrUrl.CompareNoCase(SETTINGOK) ) {……}else if ( 0 == cstrUrl.CompareNoCase(STARTCOMD) ) {*Cancel = VARIANT_TRUE;m_AutoMan.SetStart(TRUE);break;}else if (  0 == cstrUrl.CompareNoCase(STOPCMD) ) {*Cancel = VARIANT_TRUE;m_AutoMan.SetStart(FALSE);break;}}*Cancel = VARIANT_FALSE;} while (0);
}
点击停止按钮原理同点击开始按钮原理一致。此处不再赘述。
当用户选择好出发地和目的地及时间后,用户点击查询按钮。并点击“开始”按钮。我们的“人”线程就开始了自动查询操作。
查询是否存在票,有票则预订,无票则再次查询

当我们执行完一次查询后,我们要查看下搜索结果列表信息中用户选择的车次是否存在票。我们先看一下页面结构


        其查找该节点的方法如下

HRESULT CDeal12306WebPage::QueryTicketsInfo( CComPtr<IHTMLDocument2> & spDoc )
{HRESULT hr = E_FAIL;do  {CComPtr<IHTMLDocument2> spMainDoc;hr = GetMainDoc( spDoc, spMainDoc);CHECKHRPOINTER(hr, spMainDoc);CComPtr<IHTMLElement> spEnter_wElem;hr = GetEnter_wElement(spMainDoc, spEnter_wElem );CHECKHRPOINTER(hr, spEnter_wElem);CComPtr<IHTMLElement> spIDGridbox;hr = GetElementByID( spEnter_wElem, L"gridbox", spIDGridbox);CHECKHRPOINTER(hr, spIDGridbox);CComPtr<IHTMLElement> spTable;hr = GetElementByIndex( spIDGridbox, 0, spTable);CHECKHRPOINTER(hr, spTable);CComPtr<IHTMLElement> spTbody;hr = GetElementByIndex( spTable, 0, spTbody);CHECKHRPOINTER(hr, spTbody);CComPtr<IHTMLElement> spTr;hr = GetElementByIndex( spTbody, 1, spTr);CHECKHRPOINTER(hr, spTr);CComPtr<IHTMLElement> spTd;hr = GetElementByIndex(spTr, 0, spTd);CHECKHRPOINTER(hr, spTd);CComPtr<IHTMLElement> spDiv;hr = GetElementByIndex(spTd, 0, spDiv);CHECKHRPOINTER(hr, spDiv);CComPtr<IHTMLElement> spDiv2;hr = GetElementByIndex(spDiv, 0, spDiv2);CHECKHRPOINTER(hr, spDiv2);CComPtr<IHTMLElement> spTable2;hr = GetElementByIndex(spDiv2, 0, spTable2);CHECKHRPOINTER(hr, spTable2);CComPtr<IHTMLElement> spTbody2;hr = GetElementByIndex(spTable2, 0, spTbody2);CHECKHRPOINTER(hr, spTbody2);CComPtr<IHTMLElementCollection> spElemCollection;hr = GetElementCollection(spTbody2, spElemCollection );CHECKHRPOINTER(hr, spElemCollection);long lCount = 0;hr = spElemCollection->get_length(&lCount);CHECKHR(hr);for ( long lindex = 0; lindex < lCount; lindex++ ) {if ( 0 == lindex ) {continue;}CComVariant VarIndex = lindex;CComPtr<IDispatch> spDispatchElem;hr = spElemCollection->item( VarIndex, VarIndex, &spDispatchElem );CHECKHRPOINTER(hr,spDispatchElem);CComPtr<IHTMLElement> spChildTr;hr = spDispatchElem->QueryInterface(IID_IHTMLElement, (LPVOID*)& spChildTr);CHECKHRPOINTER(hr, spChildTr);hr = GetQueryInfoInTr( spChildTr );if ( SUCCEEDED(hr) ) {// 点击了订购按钮了break;}}} while (0);return hr;
}
上述代码执行到第57行时,for循环将逐个读取每列车的信息。为了最快速达到点击“预订”按钮,我将判断的操作放在GetQueryInfoInTr中。
HRESULT CDeal12306WebPage::GetQueryInfoInTr( CComPtr<IHTMLElement> & spElem)
{HRESULT hr = E_FAIL;do {CComPtr<IHTMLElementCollection> spElemCollection;hr = GetElementCollection(spElem, spElemCollection );CHECKHRPOINTER(hr, spElemCollection);long lCount = 0;hr = spElemCollection->get_length(&lCount);CHECKHR(hr);StTrainInfo stTraininfoItem;for ( long lindex = 0; lindex < lCount; lindex++ ) {CComVariant VarIndex = lindex;CComPtr<IDispatch> spDispatchElem;hr = spElemCollection->item( VarIndex, VarIndex, &spDispatchElem );CHECKHRPOINTER(hr,spDispatchElem);CComPtr<IHTMLElement> spChildTd;hr = spDispatchElem->QueryInterface(IID_IHTMLElement, (LPVOID*)& spChildTd);CHECKHRPOINTER(hr, spChildTd);hr = GetQueryInfoSubItem( spChildTd, stTraininfoItem, lindex );   CHECKHR(hr);}CHECKHR(hr);CComPtr<IHTMLElement> spTd;hr = GetElementByIndex( spElem, lCount - 1, spTd);CHECKHRPOINTER(hr, spTd);CComPtr<IHTMLElement> spButton;hr = GetElementByIndex( spTd, 0, spButton );CHECKHRPOINTER(hr, spButton);CComBSTR bstrClassName;hr = spButton->get_className(&bstrClassName);CHECKHR(hr);CString cstrClassName = bstrClassName;if ( 0 == cstrClassName.CompareNoCase(HAVETICKETSACLASS) ) {hr = spButton->click();}else {// 还没有票}m_VecTrainInfo.push_back(stTraininfoItem);} while (0);return hr;
}
我这儿做了简化:只要“预订”按钮变成可点击,即点击之。其实这儿应该做更多的判断,比如用户的席别是否有票。上述代码第44行,即是点击“预订”按钮的操作。
如果没有票,则我们点击“查询”按钮。

HRESULT CDeal12306WebPage::StartQueryInQueryPage( CComPtr<IHTMLDocument2> & spDoc )
{HRESULT hr = S_FALSE;do  {CComPtr<IHTMLElement> spQueryButton;hr = GetQueryButtonInQueryPage( spDoc, spQueryButton);CHECKHRPOINTER(hr, spQueryButton);hr = spQueryButton->click();} while (0);return hr;
}

如此,我们便实现了自动查询和自动订票的功能。

相关文章:

以数据为中心,立足六大技术支柱,英特尔推动神经拟态计算、量子计算前沿探索

近日&#xff0c;英特尔中国研究院院长宋继强围绕 “英特尔如何构建技术基石&#xff0c;驱动未来计算”为主题做了演讲。他阐述了英特尔将坚持“以数据为中心”的目标&#xff0c;并指出依托于XPU产品组合&#xff0c;英特尔通过异构整合和oneAPI软件平台来推动实现超异构计算…

Fedora 7 播放器totem

说实话&#xff0c;我喜欢这个东东&#xff0c;简约而不简单。我以前一直用mplayer&#xff0c;不过还是喜欢totem的长相。很多人说不能播放&#xff0c;可以这么做&#xff0c;让它支持全部(用mplayer的codecs)&#xff1a;(1)首先将系统已有的totem移去 # yum remove totem(2…

如何定制一款12306抢票浏览器——处理预订页面和验证码自动识别功能

判断是否进入预订页面我们先看一下预订页面的结构&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09;可以见得&#xff0c;这个页面也是嵌入了两个IFrame。关于IFrame的跨域问题&#xff0c;我已经在前一篇文章中讲述了解决办法。我判断是否是预订页面是通过两个依…

利用MTCNN和FaceNet实现人脸检测和人脸识别 | CSDN博文精选

作者 | pan_jinquan来源 | CSDN博文精选&#xff08;*点击阅读原文&#xff0c;查看作者更多文章&#xff09;人脸检测和人脸识别技术算是目前人工智能方面应用最成熟的技术了。本博客将利用MTCNN和FaceNet搭建一个实现人脸检测和人脸识别的系统。基本思路也很简单&#xff0c;…

[导入]郁闷`````[原]

阅读全文 类别&#xff1a;职场生涯 查看评论文章来源:http://hi.baidu.com/huqing7002/blog/item/b69a27082063fbd263d98619.html转载于:https://www.cnblogs.com/huqing7002/archive/2007/12/14/1007049.html

code标签的妙用

code标签的秒用是&#xff1a; 当你写了一大版的css或者html或者其他代码&#xff0c;想要去掉代码中多余的空格和换行从而达到压缩的目的的时候&#xff0c;可以新建一个html文件&#xff0c;然后把想要压缩的代码段放到code标签里&#xff0c;保存&#xff0c;浏览器浏览&…

如何定制一款12306抢票浏览器——完结篇

差不多花了一个星期的业余时间去完成了相关的编码。最后也只是使用了5篇文章将整个大题流程和使用的关键技术介绍了一下。其中有很多酸甜苦辣,其中记忆最为深刻的就是我对图像做了处理后,tesseract-ocr对验证码识别的准确度提升非常大。当我还沉浸子在这片喜悦之中时,12306将…

所有各数据库或文件的连接串定义CHM文件.

从www.connectionstrings.com 中制作生成/Files/margiex/DotnetConn.rar

钢铁侠“变身”AI布道师?小罗伯特·唐尼这次推出一部AI科普纪录片

作者 | 若名出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;穿着一身运动便服&#xff0c;脱去了铠甲的“钢铁侠”托尼斯塔克最近出现在荧屏上&#xff0c;他正与身后的AI助手互动&#xff0c;一本正经讲解着“机器学习”、“算法”这些词汇。不过&#xff0c;这个AI…

Wireshark数据抓包教程之Wireshark的基础知识

Wireshark数据抓包教程之Wireshark的基础知识 Wireshark的基础知识 在这个网络信息时代里&#xff0c;计算机安全始终是一个让人揪心的问题&#xff0c;网络安全则有过之而无不及。Wireshark作为国际知名的网络数据抓包和分析工具&#xff0c;可以广泛地应用各种领域&#xff0…

WMI技术介绍和应用——查询快捷方式、映射磁盘和虚拟内存信息

本文使用了《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。本节只是列出了WQL语句&#xff0c;具体使用参看前面的例子。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09; 因为将要介绍的三个模块都比较简单&#xff0c;故将这三…

不要痴迷蓝牙耳机了,出门选这个准没错,99W+人的选择

01有一种耳机啊它是真的不适合在长途火车上使用那就蓝牙耳机除非你带充电宝还有一种耳机啊它是真的不适合丢那就是带有充电仓的耳机因为充电仓丢了这个耳机基本上就废了02这不&#xff0c;我就经历了&#xff0c;活生生的例子出差的路上在火车上把耳机充电仓给弄丢了只剩孤零零…

结构化文件存取

纲要:AssignFile: 关联Rewrite: 创建并打开一个新文件, 如已存在则覆盖Reset: 打开已存在的文件; 追加也要用它先打开, 然后再移动指针; Append 是文本文件专用的CloseFile: 关闭FileSize: 记录数FilePos: 返回文件的当前位置Seek: 把文件指针移到指定位置(只用于结构化文件)Eo…

_00021 尼娜抹微笑伊拉克_谁的的最离奇的异常第二阶段 Jedis pool.returnResource(jedis)...

笔者博文&#xff1a;妳那伊抹微笑博客地址&#xff1a;http://blog.csdn.net/u012185296博文标题&#xff1a;_00021 妳那伊抹微笑_谁的异常最诡异第二期之 Jedis pool.returnResource(jedis)个性签名&#xff1a;世界上最遥远的距离不是天涯&#xff0c;也不是海角&#xff0…

WMI技术介绍和应用——查询系统信息

本文使用了《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。本节只是列出了WQL语句&#xff0c;具体使用参看前面的例子。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09; 本机主要知识点是Win32_ComputerSystem类。通过该类我们…

利用OpenCV实现抖音最强变脸术 | CSDN原力计划

作者 | 亓斌来源 | CSDN原力计划获奖作品&#xff08;*点击阅读原文&#xff0c;查看作者更多文章&#xff09;最近一个“最强变脸术”又火爆抖音啦&#xff0c;还不知道的朋友建议先打开抖音&#xff0c;搜索“最强变脸术”看个十来个视频再回来看这篇文章。视频看起来炫酷&am…

思科PIX防火墙的实际应用配置

PIX&#xff1a;一个合法IP完成inside、outside和dmz之间的访问 现有条件&#xff1a;100M宽带接入&#xff0c;分配一个合法的IP&#xff08;222.134.135.98&#xff09;&#xff08;只有1个静态IP是否够用&#xff1f;&#xff09;&#xff1b;PiX515e-r-DMZ-BUN1台&#xff…

CommonJS 的 AMD 规范

异步模块定义&#xff08;Asynchronous Module Definition&#xff0c;简称 AMD&#xff09;API 描述了一种定义模块的机制&#xff0c;模块及其依赖模块可以通过这种机制进行加载。该机制特别适用于浏览器。 本规范曾被称为 Modules Transport/C&#xff0c;但本规范主要不是用…

易观的大数据中台之路

作者 | 易观CTO郭炜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;本文为CSDN即将推出的《新战场&#xff1a;决胜中台》专刊的第 2 篇文章。什么是数据中台&#xff1f;中台的定义来自于投资银行&#xff0c;简单说来&#xff0c;投行当中前台是赚钱的、后台是做支…

WMI技术介绍和应用——查询系统信息和补丁包信息

本文使用了《 WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。本节只是列出了WQL语句&#xff0c;具体使用参看前面的例子。&#xff08; 转载请指明出于breaksoftware的csdn博客&#xff09;本文主要知识点是Win32_OperatingSystem和Win32_Quick…

Winform与Webform中的对话框

参考MSDNDialogResult result MessageBox.Show("见过打劫的没?", "打、打、打劫", MessageBoxButtons.OKCancel, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);switch (result){case DialogResult.OK:MessageBox.Show("你按了确定…

启动Genymotion时报错Failed to initialize backend EGL display

在启动Genymotion的时候报错&#xff1a; video card说的是显卡&#xff0c;你的显卡可能不支持 OpenGL2.0&#xff0c;或者你装的驱动有问题。解决办法&#xff1a;将驱动重新安装一下。可直接下载一个如“驱动人生“一样的驱动软件&#xff0c;把你的显卡驱动更新一下。转载…

新年新方向-斩获新职位

^_^上个星期斩获公司内部竞聘职位&#xff1a;项目管理部总经理&#xff0c;高兴&#xff0c;发展方向变了&#xff0c;以后我会多写一些项目管理的文章和大家分享。WPF的学习和分享也不会停下来&#xff0c;我要全面发展&#xff0c;做社会主义的接班人!YE!项目管理部总经理职…

清华官宣:前百度总裁张亚勤正式加盟清华大学

整理 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;12月31日&#xff0c;2019 年的最后一天&#xff0c;在大家沉浸在「总结过去」、「展望未来」之时&#xff0c;清华大学刚刚官宣了一则消息&#xff1a;前百度总裁张亚勤正式加盟清华大学&#…

WMI技术介绍和应用——查询时间信息

本文使用了《WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。本节只是列出了WQL语句&#xff0c;具体使用参看前面的例子。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09; 本文主要介绍Win32_LocalTime和Win32_UTCTime。 如何使…

问题-[VMware Workstation]断电后,重启电脑,之后就提示“内部错误”

问题现象&#xff1a;突然断电后&#xff0c;重启电脑&#xff0c;再打开VMware Workstation&#xff0c;启动不了。之后就提示“内部错误”。问题原因&#xff1a;希望高人指点。问题处理&#xff1a;关闭VMware Workstation&#xff0c;在快捷方式上&#xff0c;右击&#xf…

FC SAN与IP SAN的比较

SAN&#xff08;Storage Area Network&#xff0c;存储区域网络&#xff09;是一个由存储设备和系统部件构成的网络。所有的通信都在一个与应用网络隔离的单独的网络上完成&#xff0c;可以被用来集中和共享存储资源。SAN不但提供了对数据设备的高性能连接&#xff0c;提高了数…

“数学不行,干啥也不行!”骨灰级程序员:其实你们都是瞎努力

编程圈一直都流传着一个段子&#xff1a;一流程序员靠数学&#xff0c;二流程序员靠算法&#xff0c;末端程序员靠百度&#xff0c;低端看高端就是黑魔法。懂的人其实都知道&#xff0c;这不是段子&#xff0c;其实就是程序员的真实写照。想一想&#xff0c;我们日常学习、求职…

WMI技术介绍和应用——查询系统服务

本文使用了《 WMI技术介绍和应用——使用VC编写一个半同步查询WMI服务的类》中代码做为基础。本节只是列出了WQL语句&#xff0c;具体使用参看前面的例子。&#xff08; 转载请指明出于breaksoftware的csdn博客&#xff09;本文主要介绍Win32_Service类。 如何使用WMI枚举系统中…

送书 | 2020年新一天,用这本书开启你的NLP学习之路!

本文选自电子工业出版社博文视点新书《大数据智能&#xff1a;数据驱动的自然语言处理技术》。本书作者&#xff1a;清华大学刘知远、薄言RSVP.ai崔安颀、腾讯张开旭、清华大学韩文弢、中国人民大学赵鑫、厦门大学苏劲松、罗格斯大学张永锋、北京大学严睿、哈尔滨工业大学&…