• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評論-2670  文章-0  trackbacks-0

            在S1死程群@kula的鼓勵下,我開始使用kula提供的api來操作那個傻逼的“鳥窩”網站(https://www.niaowo.me)。不過由于我自己在業余時間寫的程序都喜歡用C++和Windows API,因此我琢磨了幾天,真的讓我用C++給寫了出來。

            我寫了一個HttpUtility庫來實現C++操作http/https服務的功能,這份代碼可以在這里獲得:

            HttpUtility.h:http://gac.codeplex.com/SourceControl/changeset/view/95641#2295555
            HttpUtility.cpp:http://gac.codeplex.com/SourceControl/changeset/view/95641#2295554

            使用的時候很簡單,只需要HttpRequest里面填滿了參數,然后就可以用HttpQuery參數獲得一個HttpResponse類型,這個類型里面寫滿了http服務器的返回值、返回內容和cookie等的數據。譬如說用來post來登陸鳥窩,然后拿到cookie之后查詢首頁的所有帖子,大概就可以這么寫:

            WString NestleGetSession(const WString& username, const WString& password, const WString& apiKey, const WString& apiSecret)
            {
                WString body=L"api_key="+apiKey+L"&api_secret="+apiSecret+L"&username="+username+L"&password="+password;

                HttpRequest request;
                HttpResponse response;

                request.SetHost(L"https://www.niaowo.me/account/token/");
                request.method=L"POST";
                request.contentType=L"application/x-www-form-urlencoded";
                request.SetBodyUtf8(body);
                HttpQuery(request, response);

                if(response.statusCode==200)
                {
                    return response.cookie;
                }
                else
                {
                    return L"";
                }
            }

            WString NestleGetXml(const WString& path, const WString& cookie)
            {
                HttpRequest request;
                HttpResponse response;

                request.SetHost(L"https://www.niaowo.me"+path+L".xml");
                request.method=L"GET";
                request.cookie=cookie;
                request.acceptTypes.Add(L"application/xml");
                HttpQuery(request, response);
               

                if(response.statusCode==200)
                {
                    return response.GetBodyUtf8();
                }
                else
                {
                    return L"";
                }
            }

            于是我們終于獲得了一個保存在vl::WString的xml字符串了,那怎么辦呢?這個時候需要出動IXMLDOMDocument2來解析我們的xml。只要裝了IE的計算機上都是有IXMLDOMDocument2的,而不裝IE的Windows PC是不存在的,因此我們總是可以大膽的使用。當然,用IXMLDOMDocument直接來遍歷什么東西特別的慢,所以我們需要的是xpath。xpath對于xml就跟regex對于字符串一樣,可以直接查詢出我們要的東西。首先看一下如何操作IXMLDOMDocument2接口:

            IXMLDOMNodeList* XmlQuery(IXMLDOMNode* pDom, const WString& xpath)
            {
                IXMLDOMNodeList* nodes=0;
                BSTR xmlQuery=SysAllocString(xpath.Buffer());
                if(xmlQuery)
                {
                    HRESULT hr=pDom->selectNodes(xmlQuery, &nodes);
                    if(FAILED(hr))
                    {
                        nodes=0;
                    }
                    SysFreeString(xmlQuery);
                }
                return nodes;
            }

            WString XmlReadString(IXMLDOMNode* node)
            {
                WString result;
                BSTR text=0;
                HRESULT hr=node->get_text(&text);
                if(SUCCEEDED(hr))
                {
                    const wchar_t* candidateItem=text;
                    result=candidateItem;
                    SysFreeString(text);
                }
                return result;
            }

            void XmlReadMultipleStrings(IXMLDOMNodeList* textNodes, List<WString>& candidates, int max)
            {
                candidates.Clear();
                while((int)candidates.Count()<max)
                {
                    IXMLDOMNode* textNode=0;
                    HRESULT hr=textNodes->nextNode(&textNode);
                    if(hr==S_OK)
                    {
                        candidates.Add(XmlReadString(textNode));
                        textNode->Release();
                    }
                    else
                    {
                        break;
                    }
                }
            }

            IXMLDOMDocument2* XmlLoad(const WString& content)
            {
                IXMLDOMDocument2* pDom=0;
                HRESULT hr=CoCreateInstance(__uuidof(DOMDocument60), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDom));
                if(SUCCEEDED(hr))
                {
                    pDom->put_async(VARIANT_FALSE);
                    pDom->put_validateOnParse(VARIANT_FALSE);
                    pDom->put_resolveExternals(VARIANT_FALSE);

                    BSTR xmlContent=SysAllocString(content.Buffer());
                    if(xmlContent)
                    {
                        VARIANT_BOOL isSuccessful=0;
                        hr=pDom->loadXML(xmlContent, &isSuccessful);
                        if(!(SUCCEEDED(hr) && isSuccessful==VARIANT_TRUE))
                        {
                            pDom->Release();
                            pDom=0;
                        }
                        SysFreeString(xmlContent);
                    }
                }
                return pDom;
            }

            有了這幾個函數之后,我們就可以干下面的事情,譬如說從鳥窩首頁下載第一頁的所有topic的標題:

            WString xml=NestleGetXml(L”/topics”, cookie);
            IXMLDOMDocument2* pDom=XmlLoad(xml);
            List<WString> titles;
            IXMLNodeList* nodes=XmlQuery(pDom, L”/hash/topics/topic/title/text()”);
            XmlReadMultipleStrings(nodes, titles, 100);

            為什么上面的xpath是hash/topics/topic/title/text()呢?因為這個xml的內容大概類似于:
            <hash>
                <topics>
                    <topic>
                        <title>TITLE</title>

            剩下的大家就去看代碼吧。這個故事告訴我們,只要有一個合適的封裝,C++寫起這些本來應該讓C#來寫的東西也不是那么的煩人的,啊哈哈哈哈。

            posted on 2012-10-26 23:19 陳梓瀚(vczh) 閱讀(3901) 評論(1)  編輯 收藏 引用 所屬分類: C++

            評論:
            # re: 使用C++和Windows API操作基于http協議的xml service 2012-10-27 05:50 | huliang
            牛逼~~ 一開始還真看成是C#的 HttpResponse 了  回復  更多評論
              
            亚洲AV日韩AV永久无码久久| 久久久久香蕉视频| AV无码久久久久不卡蜜桃 | 一本一本久久A久久综合精品 | 久久久久久久女国产乱让韩| 日韩欧美亚洲综合久久| 久久99国产综合精品| 久久久久久噜噜精品免费直播| 久久久国产99久久国产一| 97精品久久天干天天天按摩| 久久夜色撩人精品国产| 国产精品一区二区久久| 久久人人爽人人爽人人片AV东京热| 99re久久精品国产首页2020| 久久国产精品二国产精品| 久久精品国产亚洲av日韩 | 久久午夜无码鲁丝片| 午夜视频久久久久一区 | 狠狠精品久久久无码中文字幕 | 久久久无码人妻精品无码| 免费一级欧美大片久久网| 精品久久久久久久| 久久天天躁狠狠躁夜夜96流白浆 | 色综合久久88色综合天天 | 996久久国产精品线观看| 日产精品99久久久久久| 亚洲精品99久久久久中文字幕| 婷婷久久综合九色综合98| 久久精品国产亚洲AV麻豆网站| 人人妻久久人人澡人人爽人人精品| 国产午夜精品久久久久九九| 91精品国产高清久久久久久io | 久久国产免费直播| 久久93精品国产91久久综合| 国产高清国内精品福利99久久| 国产V亚洲V天堂无码久久久| 精品久久久久久成人AV| 久久精品黄AA片一区二区三区| 久久精品国产亚洲av日韩| 色综合久久中文字幕无码| 久久精品国产亚洲av日韩 |