• <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 了  回復  更多評論
              
            亚洲国产综合久久天堂| 久久久久久国产a免费观看黄色大片 | 伊人色综合久久天天人守人婷 | 综合久久国产九一剧情麻豆| 久久天天躁狠狠躁夜夜2020老熟妇 | 无码超乳爆乳中文字幕久久| 丁香色欲久久久久久综合网| 亚洲AV无码久久精品成人 | 99久久做夜夜爱天天做精品| 久久天天躁狠狠躁夜夜不卡| 伊人久久无码中文字幕| 久久er99热精品一区二区| 久久91精品国产91久久户| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 久久婷婷五月综合国产尤物app | 91精品国产91热久久久久福利| 色综合久久久久| 精品久久久久久99人妻| 一本综合久久国产二区| 国产激情久久久久久熟女老人| 日产精品久久久久久久性色| 国产美女久久久| 久久强奷乱码老熟女| 亚洲精品乱码久久久久久中文字幕| 久久免费的精品国产V∧| 99久久婷婷国产一区二区| 一级女性全黄久久生活片免费| 国产亚洲精久久久久久无码77777| 97久久精品人妻人人搡人人玩| yellow中文字幕久久网| 亚洲七七久久精品中文国产 | 亚洲AV伊人久久青青草原| 久久99精品久久久久久动态图 | 精品久久久噜噜噜久久久| 久久久精品国产亚洲成人满18免费网站| 色99久久久久高潮综合影院| WWW婷婷AV久久久影片| 无码国内精品久久综合88| 久久久精品免费国产四虎| 亚洲欧美伊人久久综合一区二区| 久久亚洲精品视频|