• <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) 閱讀(3907) 評論(1)  編輯 收藏 引用 所屬分類: C++

            評論:
            # re: 使用C++和Windows API操作基于http協議的xml service 2012-10-27 05:50 | huliang
            牛逼~~ 一開始還真看成是C#的 HttpResponse 了  回復  更多評論
              
            日产精品久久久久久久| 久久精品国产2020| 精品久久久久中文字幕一区| 大香网伊人久久综合网2020| 青春久久| 精品久久香蕉国产线看观看亚洲| 久久综合丁香激情久久| 亚洲国产精品成人久久蜜臀| 久久久一本精品99久久精品66| 日韩一区二区久久久久久| 久久久国产视频| 国产精品一久久香蕉国产线看| 久久精品亚洲乱码伦伦中文| 无码国内精品久久人妻| 久久九九久精品国产免费直播| 国产亚洲精久久久久久无码77777| 国产V综合V亚洲欧美久久| 久久亚洲欧洲国产综合| 日本免费久久久久久久网站 | 性做久久久久久久| 中文精品久久久久国产网址| 影音先锋女人AV鲁色资源网久久| 国产精品成人久久久久久久| 久久久久久国产精品无码超碰 | 久久人与动人物a级毛片| 国产精品久久久久久久 | 精品久久久久久无码专区| 青青热久久国产久精品| 久久99精品国产麻豆宅宅| 久久精品夜夜夜夜夜久久| 亚洲伊人久久大香线蕉综合图片| 午夜精品久久久久9999高清| 欧美激情精品久久久久| 国产美女久久精品香蕉69| 日日躁夜夜躁狠狠久久AV| 99蜜桃臀久久久欧美精品网站| 久久综合视频网| 国产亚洲美女精品久久久2020| 国产69精品久久久久观看软件| 伊人久久一区二区三区无码| 久久无码国产|