在上一篇文章《调用网络API》中,我仅仅讲述了怎样直观的使用API接口以及调用API后返回的结果,本文则从程序实现的角度来实现API的调用。当然本程序的实现也是借助于扇贝网的API接口文档http://www.shanbay.com/help/developer/api/。
由API文档可知,要想调用其API,必须先注冊。因此,我就注冊了,账户名为nineheadedbird。密码为123456。
显然。我们要查词,首先必须得登录该账户。
假设用浏览器,那就非常easy,仅仅需单纯的输入username与password就能够了。可实际上。这一操作并不简单。仅仅是浏览器为我们做了这一切。
假设我们要通过程序来实现上述功能的话,就须要用到Qt中的get()函数了,而发送请求的内容格式就至关重要了。
查看请求格式
我们能够通过浏览器来查看请求格式:首先用谷歌浏览器(其它浏览器也能够。只是你要百度一下怎么来查看这些格式)打开扇贝网的登录界面http://www.shanbay.com/accounts/login/ ,在谷歌浏览器的设置中单击开发人员选项。然后刷新一下页眉,就会出现例如以下的界面:
然后点击右边的第一个文件login。就会出现以下的内容:
从上图能够看出,内容分为三类:General、Response Headers、Request Headers
在General中能够看到Request Method为GET(一般还有还有一种方式POST。这在Qt中都有相应的函数),Status Code为200表示正常。在Response Headers 中我们关注的是Set-Cookie中的csrftoken的值,由于这在我们登录时须要这个值。我们最关心的是Request Headers的内容,这部分就是我们请求函数中内容格式!參考上述的详细内容例如以下:
我们的程序能够写成例如以下的方式:
QNetworkRequest request;
request.setUrl(QUrl("http://www.shanbay.com/accounts/login/"));
request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
request.setRawHeader("Cache-Control","max-age=0");
request.setRawHeader("Connection","keep-alive");
request.setRawHeader("Host","www.shanbay.com");
request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
http->get(request);
当我们运行上述的请求之后,server就会作答。作答的内容就是上面的Response Headers,而我们须要的是Set-Cookie中的csrftoken的值。
在Qt中,我们将程序中finished信号与我们定义的槽关联,即每当网络应答结束时,都会发射这个信号。从而触发该槽函数的运行。来处理server的应答内容。在程序中。getCookie函数就是来获取csrftoken的值。
用户登录
获得csrftoken的值后,我们就须要实现登录操作了。
除了上述的请求格式之外。我们还须要加入csrftoken的值、用户名以及密码。
详细格式可见下述代码:
QNetworkRequest request; request.setUrl(QUrl("http://www.shanbay.com/accounts/login/"));
request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
request.setRawHeader("Cache-Control","max-age=0");
request.setRawHeader("Connection","keep-alive");
request.setRawHeader("Host","www.shanbay.com");
request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
request.setRawHeader("Origin","http//www.shanbay.com");
request.setRawHeader("Referer","http://www.shanbay.com/accounts/login/");
request.setRawHeader("Host","www.shanbay.com");
request.setRawHeader("Content-Type","application/x-www-form-urlencoded");
QByteArray postData;
postData.append(QString("csrfmiddlewaretoken=%1&").arg(sessionid));//csrftoken的值
postData.append(QString("username=%1&password=%2&").arg(QUrl::toPercentEncoding(username).constData()).arg(password));//用户名及密码
postData.append("login=登录&continue=home&u=1&next=");
request.setHeader(QNetworkRequest::ContentLengthHeader,postData.size());
httpAction=LoginAction;
http->post(request,postData);
调用API
完毕登录之后,就能够进行查词和添词操作了。除了上述提到的请求头格式之外,仅仅须要遵守API规范(《调用网络API》中提到请求格式)就可以。查词及添词的程序实现分别例如以下:
void netWork::queryWord(const QString &word)//查词操作
{
QNetworkRequest request;
request.setUrl(QUrl("http://www.shanbay.com/api/word/"+word));
request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3");
request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
request.setRawHeader("Cache-Control","max-age=0");
request.setRawHeader("Connection","keep-alive");
request.setRawHeader("Host","www.shanbay.com");
request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
httpAction=QueryWordAction;
http->get(request);}
void netWork::addWord(const QString &word)//添词操作
{
if(word.isEmpty())
qDebug()<<"你的输入有误";
else
{
QNetworkRequest request;
request.setUrl(QUrl("http://www.shanbay.com/api/learning/add/"+word));
request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3");
request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
request.setRawHeader("Cache-Control","max-age=0");
request.setRawHeader("Connection","keep-alive");
request.setRawHeader("Host","www.shanbay.com");
request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
httpAction=AddWordAction;
http->get(request);
}
}
完整流程
至此,API调用的各个功能已经实现。以下给出程序的总体思路:首先获取csrftoken的值(每次都不同);然后利用用户名、密码及csrftoken的值来登录;接着就能够调用API了。
在程序中,每当进行请求,都会在replyfinished函数中用case语句来分别处理这些请求相应的应答。注意,不要连续的进行请求,否则可能发生冲突。
在程序中,为了防止冲突,我在connectNet请求后,在其应答处理函数中再进行loginShanbay的登录。然后在其应答函数中进行queryWord查词请求,然后在其相应的应答处理函数中进行addWord添词请求。其结果显演示样例如以下:
程序实现
以下我们给出详细的程序实现(qt 5版本号,使用到网络类,须要加上QT += network):首先建立一个空的qt子项目,然后加入一个名为netWork的类,继承自QObject,然后再加入一个名为main的源文件,这三个文件的内容分别例如以下:
1、network.h文件
Q_OBJECTpublic: explicit netWork(QObject *parent = 0); // ~netWork();
enum HttpAction{NoAction,NetStudy,GetSessionidAction,LoginAction,QueryWordAction,AddWordAction,AddExampleAction,QueryWordExamplesAction};
HttpAction httpAction;
QNetworkAccessManager * http;
QString sessionid;
QString queryword;//要查询的单词
QString nickname;
QString username;
QString password; bool isBusy; QString getCookie(const QString &name); void loginShanbay(); void queryWord(const QString &word); void queryExamples(QString learningid); void connectNet(QString username="nineheadedbird", QString password="123456"); void addWord(const QString &word);
signals://这里的信号都没实用到
void connectSuccess();
void connectFail(); void verifySuccess(); void verifyFail(); void NetState(bool);public slots: void replyfinished(QNetworkReply*);
};
2、network.cpp文件
#include "network.h"#include
#include netWork::netWork(QObject *parent) : QObject(parent) {
http=new QNetworkAccessManager(this);
http->setCookieJar(new QNetworkCookieJar(this)); connect(http,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyfinished(QNetworkReply*)));//将finished信号与我们定义的槽关联,每当网络应答结束时,都会发射这个信号
isBusy=true;
}QString netWork::getCookie(const QString &name)//用于获得SessionId{
foreach(QNetworkCookie cookie , http->cookieJar()->cookiesForUrl(QUrl("http://www.shanbay.com/")))
{ if(cookie.name()==name)
{ qDebug()<<"csrftoken:"<
return cookie.value();}
} return "";
}void netWork::connectNet(QString username, QString password)//连接网络,使用默认的username与password{ this->username=username; this->password=password;
QNetworkRequest request;
request.setUrl(QUrl("http://www.shanbay.com/accounts/login/"));
request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
request.setRawHeader("Cache-Control","max-age=0");
request.setRawHeader("Connection","keep-alive");
request.setRawHeader("Host","www.shanbay.com");
request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
httpAction=GetSessionidAction;
http->get(request);
}void netWork::replyfinished(QNetworkReply *reply)//每当运行站点应答结束后,就会运行该槽函数{
QVariant status_code=reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); qDebug()<<"code_state="<<status_code;//网络状态,200代表正常,302代表重定向,404:not found等等</status_code;
if(status_code==QVariant::Invalid)//推断是否连接到站点,即当前设备是否能上网
emit NetState(false); else
emit NetState(true); switch(httpAction)//依据我们都进行了什么网络请求
{ case NoAction: break; case GetSessionidAction://获取SessionId
sessionid=getCookie("csrftoken"); if(!sessionid.isEmpty())
{ emit connectSuccess(); qDebug()<<("已经连接扇贝网,正在验证用户名密码..."); loginShanbay();
}else
{
emit connectFail(); qDebug()<<("Cannot connect to the website!");
} break; case LoginAction: //进行登录操作
httpAction=NoAction; if(0==reply->readAll().size())
{
QString nickname=QUrl::fromPercentEncoding(getCookie("username").toLatin1()); emit verifySuccess(); qDebug()<<"Successfully Login"<
"hello" );}else
{
emit verifyFail(); qDebug()<<"Failed to login!";
} break; case QueryWordAction://查词操作
qDebug()<<"----query word----"; qDebug()<
readAll();//读取查词结果
addWord("hello");//加入单词到单词本
break; case AddWordAction://添词操作
qDebug()<<"---add word----"; qDebug()<
readAll();//返回加入词语的learning_id break; default:break;
}
}void netWork::loginShanbay()//账户密码的登录操作{
QNetworkRequest request;
request.setUrl(QUrl("http://www.shanbay.com/accounts/login/"));
request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
request.setRawHeader("Cache-Control","max-age=0");
request.setRawHeader("Connection","keep-alive");
request.setRawHeader("Host","www.shanbay.com");
request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
request.setRawHeader("Origin","http//www.shanbay.com");
request.setRawHeader("Referer","http://www.shanbay.com/accounts/login/");
request.setRawHeader("Host","www.shanbay.com");
request.setRawHeader("Content-Type","application/x-www-form-urlencoded");
QByteArray postData;
postData.append(QString("csrfmiddlewaretoken=%1&").arg(sessionid));
postData.append(QString("username=%1&password=%2&").arg(QUrl::toPercentEncoding(username).constData()).arg(password));
postData.append("login=登录&continue=home&u=1&next=");
request.setHeader(QNetworkRequest::ContentLengthHeader,postData.size());
httpAction=LoginAction;
http->post(request,postData);
}void netWork::queryWord(const QString &word)//查词操作{
QNetworkRequest request;
request.setUrl(QUrl("http://www.shanbay.com/api/word/"+word));
request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3");
request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
request.setRawHeader("Cache-Control","max-age=0");
request.setRawHeader("Connection","keep-alive");
request.setRawHeader("Host","www.shanbay.com");
request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
httpAction=QueryWordAction;
http->get(request);
}void netWork::addWord(const QString &word)//添词操作{ if(word.isEmpty()) qDebug()<<"你的输入有误"; else
{
QNetworkRequest request;
request.setUrl(QUrl("http://www.shanbay.com/api/learning/add/"+word));
request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3");
request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8");
request.setRawHeader("Cache-Control","max-age=0");
request.setRawHeader("Connection","keep-alive");
request.setRawHeader("Host","www.shanbay.com");
request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7");
httpAction=AddWordAction;
http->get(request);
}
}
3、main.cpp文件
netWork *nW = new netWork(); //
nW->connectNet(); // nW->loginShanbay();
// nW->queryWord("hello");
return a.exec();
}
原文始发于微信公众号(汇编语言):【Qt编程】基于Qt的词典开发系列<八>--用户登录及API调用的实现
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论