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

简介: 在上一篇文章《调用网络API》中,我只讲述了如何直观的使用API接口以及调用API后返回的结果,本文则从程序实现的角度来实现API的调用,当然本程序的实现也是借助于扇贝网的API接口文档http://www.shanbay.com/help/developer/api/。

在上一篇文章《调用网络API》中,我只讲述了如何直观的使用API接口以及调用API后返回的结果,本文则从程序实现的角度来实现API的调用,当然本程序的实现也是借助于扇贝网的API接口文档http://www.shanbay.com/help/developer/api/


API文档可知,要想调用其API,必须先注册。因此,我就注册了,账户名为nineheadedbird, 密码为123456。显然,我们要查词,首先必须得登录该账户。如果用浏览器,那就很简单,只需单纯的输入用户名和密码就可以了。可实际上,这一操作并不简单,只是浏览器为我们做了这一切。如果我们要通过程序来实现上述功能的话,就需要用到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);

当我们执行上述的请求之后,服务器就会作答,作答的内容就是上面的Response Headers,而我们需要的是Set-Cookie中的csrftoken的值。在Qt中,我们将程序中finished信号与我们定义的槽关联,即每当网络应答结束时,都会发射这个信号,从而触发该槽函数的执行,来处理服务器的应答内容。在程序中,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文件

#ifndef NETWORK_H
#define NETWORK_H


#include <QObject>
#include <QtNetwork/QNetworkAccessManager>
#include<QtNetwork/QNetworkReply>
#include<QtNetwork/QNetworkRequest>
#include<QtNetwork/QNetworkCookie>
#include<QtNetwork/QNetworkCookieJar>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
#include<QString>
#include<QDebug>
#include<QList>
#include<QUrl>
#include<QByteArray>

class netWork : public QObject //由于程序文件直接摘自整个项目文件,所以程序中有关的定义或函数没有使用,但是这个程序可以单独运行
{
    Q_OBJECT
public:
    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<QList>
#include<QDesktopServices>
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:"<<cookie.value();
                return cookie.value();
            }
    }
        return "";
}
void netWork::connectNet(QString username, QString 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等等
    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"<<nickname;
            queryWord("hello");
        }else
        {
            emit verifyFail();
            qDebug()<<"Failed to login!";
        }
        break;

    case QueryWordAction://查词操作
        qDebug()<<"----query word----";
        qDebug()<<reply->readAll();//读取查词结果

        addWord("hello");//添加单词到单词本
        break;
    case AddWordAction://添词操作
        qDebug()<<"---add word----";
        qDebug()<<reply->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 <QApplication>
#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的词典开发系列

  1. 词典框架设计及成品展示
  2. 本地词典的设计
  3. 开始菜单的设计
  4. 无边框窗口的缩放与拖动
  5. 无边框窗口的拖动
  6. 界面美化设计
  7. 调用网络API
  8. 用户登录及API调用的实现
  9. JSON数据解析
  10. 国际音标的显示
  11. 系统托盘的显示
  12. 调用讲述人
  13. 音频播放
  14. 自动补全功能
  15. HTML特殊字符及正则表达式
  16. 后序

作品下载地址(发布版):http://download.csdn.net/detail/tengweitw/8548767
作品下载地址(绿色版):http://download.csdn.net/detail/tengweitw/8830495
源码下载地址:http://download.csdn.net/detail/tengweitw/8830503


原文:http://blog.csdn.net/tengweitw/article/details/45932429

作者:nineheadedbird

目录
相关文章
|
1天前
|
安全 搜索推荐 数据挖掘
虾皮店铺商品API接口的开发、运用与收益
虾皮(Shopee)作为东南亚领先的电商平台,通过开放API接口为商家和开发者提供了全面的数据支持。本文详细介绍虾皮店铺商品API的开发与运用,涵盖注册认证、API文档解读、请求参数设置、签名生成、HTTP请求发送及响应解析等步骤,并提供Python代码示例。API接口广泛应用于电商导购、价格比较、商品推荐、数据分析等场景,带来提升用户体验、增加流量、提高运营效率等收益。开发者需注意API密钥安全、请求频率控制及遵守使用规则,确保接口稳定可靠。虾皮API推动了电商行业的创新与发展。
47 31
|
4天前
|
存储 搜索推荐 API
拼多多根据ID取商品详情原数据API接口的开发、运用与收益
拼多多作为中国电商市场的重要参与者,通过开放平台提供了丰富的API接口,其中根据ID取商品详情原数据的API接口尤为重要。该接口允许开发者通过编程方式获取商品的详细信息,为电商数据分析、竞品分析、价格监测、商品推荐等多个领域带来了丰富的应用场景和显著的收益。
27 10
|
3天前
|
JSON 供应链 搜索推荐
淘宝APP分类API接口:开发、运用与收益全解析
淘宝APP作为国内领先的购物平台,拥有丰富的商品资源和庞大的用户群体。分类API接口是实现商品分类管理、查询及个性化推荐的关键工具。通过开发和使用该接口,商家可以构建分类树、进行商品查询与搜索、提供个性化推荐,从而提高销售额、增加商品曝光、提升用户体验并降低运营成本。此外,它还能帮助拓展业务范围,满足用户的多样化需求,推动电商业务的发展和创新。
18 5
|
7天前
|
JSON API 开发者
Lazada 商品评论列表 API 接口:开发、应用与收益
Lazada作为东南亚领先的电商平台,其商品评论数据蕴含丰富信息。通过开发和利用Lazada商品评论列表API接口,企业可深入挖掘这些数据,优化产品、营销和服务,提升客户体验和市场竞争力。该API基于HTTP协议,支持GET、POST等方法,开发者需注册获取API密钥,并选择合适的编程语言(如Python)进行开发。应用场景包括竞品分析、客户反馈处理及精准营销,帮助企业提升销售业绩、降低运营成本并增强品牌声誉。
23 2
|
9天前
|
监控 搜索推荐 API
京东按图搜索京东商品(拍立淘)API接口的开发、应用与收益
京东通过开放商品详情API接口,尤其是按图搜索(拍立淘)API,为开发者、企业和商家提供了创新空间和数据支持。该API基于图像识别技术,允许用户上传图片搜索相似商品,提升购物体验和平台竞争力。开发流程包括注册账号、获取密钥、准备图片、调用API并解析结果。应用场景涵盖电商平台优化、竞品分析、个性化推荐等,为企业带来显著收益,如增加销售额、提高利润空间和优化用户体验。未来,随着数字化转型的深入,该API的应用前景将更加广阔。
51 1
|
23天前
|
人工智能 自然语言处理 API
Multimodal Live API:谷歌推出新的 AI 接口,支持多模态交互和低延迟实时互动
谷歌推出的Multimodal Live API是一个支持多模态交互、低延迟实时互动的AI接口,能够处理文本、音频和视频输入,提供自然流畅的对话体验,适用于多种应用场景。
71 3
Multimodal Live API:谷歌推出新的 AI 接口,支持多模态交互和低延迟实时互动
|
10天前
|
JSON 安全 API
淘宝商品详情API接口(item get pro接口概述)
淘宝商品详情API接口旨在帮助开发者获取淘宝商品的详细信息,包括商品标题、描述、价格、库存、销量、评价等。这些信息对于电商企业而言具有极高的价值,可用于商品信息展示、市场分析、价格比较等多种应用场景。
|
18天前
|
前端开发 API 数据库
Next 编写接口api
Next 编写接口api
|
25天前
|
XML JSON 缓存
阿里巴巴商品详情数据接口(alibaba.item_get) 丨阿里巴巴 API 实时接口指南
阿里巴巴商品详情数据接口(alibaba.item_get)允许商家通过API获取商品的详细信息,包括标题、描述、价格、销量、评价等。主要参数为商品ID(num_iid),支持多种返回数据格式,如json、xml等,便于开发者根据需求选择。使用前需注册并获得App Key与App Secret,注意遵守使用规范。
|
23天前
|
JSON API 开发者
淘宝买家秀数据接口(taobao.item_review_show)丨淘宝 API 实时接口指南
淘宝买家秀数据接口(taobao.item_review_show)可获取买家上传的图片、视频、评论等“买家秀”内容,为潜在买家提供真实参考,帮助商家优化产品和营销策略。使用前需注册开发者账号,构建请求URL并发送GET请求,解析响应数据。调用时需遵守平台规定,保护用户隐私,确保内容真实性。