【Qt编程】基于Qt的词典开发系列<八>--用户登录及API调用的实现

admin 2022年6月27日08:10:10评论26 views字数 10856阅读36分11秒阅读模式

在上一篇文章《调用网络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/ ,在谷歌浏览器的设置中单击开发人员选项。然后刷新一下页眉,就会出现例如以下的界面:
【Qt编程】基于Qt的词典开发系列<八>--用户登录及API调用的实现

然后点击右边的第一个文件login。就会出现以下的内容:
【Qt编程】基于Qt的词典开发系列<八>--用户登录及API调用的实现

从上图能够看出,内容分为三类General、Response Headers、Request Headers
General中能够看到Request Method为GET(一般还有还有一种方式POST。这在Qt中都有相应的函数),Status Code为200表示正常。在Response Headers 中我们关注的是Set-Cookie中的csrftoken的值,由于这在我们登录时须要这个值。我们最关心的是Request Headers的内容,这部分就是我们请求函数中内容格式!參考上述的详细内容例如以下:
【Qt编程】基于Qt的词典开发系列<八>--用户登录及API调用的实现

我们的程序能够写成例如以下的方式:

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编程】基于Qt的词典开发系列&lt;八&gt;--用户登录及API调用的实现


程序实现

以下我们给出详细的程序实现(qt 5版本号,使用到网络类,须要加上QT += network):首先建立一个空的qt子项目,然后加入一个名为netWork的类,继承自QObject,然后再加入一个名为main的源文件,这三个文件的内容分别例如以下:
1、network.h文件


#ifndef NETWORK_H#define NETWORK_H#include #include #include#include#include#include#include #include #include #include #include#include#include#include#includeclass netWork : public QObject //由于程序文件直接摘自整个项目文件,所以程序中有关的定义或函数没有使用,可是这个程序能够单独运行{ 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*);
};#endif // NETWORK_H

2、network.cpp文件


#include "network.h"#include#includenetWork::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文件

#include #include "network.h"int main(int argc, char *argv[]){    QApplication a(argc, argv);
netWork *nW = new netWork(); // nW->connectNet(); // nW->loginShanbay(); // nW->queryWord("hello"); return a.exec();}


原文始发于微信公众号(汇编语言):【Qt编程】基于Qt的词典开发系列&lt;八&gt;--用户登录及API调用的实现

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年6月27日08:10:10
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【Qt编程】基于Qt的词典开发系列&lt;八&gt;--用户登录及API调用的实现http://cn-sec.com/archives/1145323.html

发表评论

匿名网友 填写信息