With the encouragement of the S1 dead end group @ kula, I began to use the APIS provided by kula to operate the silly "Bird's Nest" website (https://www.niaowo.me ). However, because I like to use C ++ and Windows APIs for programs I write in my spare time, I have been thinking about it for a few days and I have actually written it in C ++.
I wrote an HttpUtility library to implement C ++'s function of operating http/https services. This code can be obtained here:
It is easy to use. You only need to fill the HttpRequest with parameters, and then you can use the HttpQuery parameter to obtain an HttpResponse type, this type is full of data such as http server return values, returned content, and cookies. For example, you can use post to log on to the bird's nest, and then query all the posts on the home page after obtaining the cookie. You can write it like this:
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 "";
}
}
So we finally got an xml string stored in vl: WString. What should we do? In this case, IXMLDOMDocument2 needs to be dispatched to parse our xml. As long as IXMLDOMDocument2 is installed on the computer where IE is installed, Windows PC without IE does not exist, so we can always use it boldly. Of course, it is very slow to use IXMLDOMDocument to traverse something directly, so what we need is xpath. Xpath is the same for xml as regex for strings. You can directly query what we want. First, let's take a look at how to operate the IXMLDOMDocument2 interface:
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;
}
With these functions, we can do the following, for example, downloading the title of all topics on the first page from the Bird's Nest homepage:
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 );
Why is the above xpath hash/topics/topic/title/text? Because the xml content is similar:
<Hash>
<Topics>
<Topic>
<Title> TITLE </title>
...
Let's look at the code for the rest. This story tells us that as long as there is a proper encapsulation, C ++ is not so annoying to write the things that should have been written by C.