源码下载
调用新浪微博开放接口,首先要到新浪服务器进行认证,新浪微博目前采用的是OAuth2.0认证,google了一下OAuth2.0认证过程大概如下:
1.待着你的应用app key去新浪服务器,新浪收到后会返回认证页面;
2.当用户授权给你的应用后,服务器 会返回一个code给你;
3.待着你的app key、app secret和服务器返回的code再去新浪服务器,服务器会返回一个access_token给你。
然后访问接口的时候记得待着这个access_token就行了。
不知道讲对了没有,目前我的程序的确就是这么做的。
其实新浪提供了很多本版的sdk,本文就不研究了,直接使用Qt自带的QNetworkAccessManager发送请求和接受应答。
在网上搜了一个qt的http请求帮助类,挺好用的,源码如下:
头文件:
#ifndef HTTPCLIENT_H
#define HTTPCLIENT_H
#include
#include
#include
#include
#include
#include
class HttpClient : public QObject
{
Q_OBJECT
public:
explicit HttpClient(QObject *parent = 0);
~HttpClient();
//http get请求
QString get(QNetworkRequest& request);
//http post请求
QString post(QNetworkRequest& request, const QByteArray& data);
//是否发生网络错误
bool hasNetworkError(){ return this->m_hasNetworkError; }
//获取网络连接错误代码
int getNetworkErrorCode(){ return this->m_networkErrorCode; }
//网络连接是否完成
bool isHttpFinish(){ return this->m_isFinished; }
//设置超时
void setTimeOutLimit(int time);
signals:
public slots:
//http请求完成
void httpRequestFinished(QNetworkReply* reply);
//请求超时处理
void timeOutHandler();
//网络错误处理
void networkErrorHandler(QNetworkReply::NetworkError error);
private:
QNetworkReply* m_pNetworkReply;
QNetworkAccessManager *m_pNetworkMgr;
bool m_hasNetworkError;//是否发生网络错误
int m_networkErrorCode;//错误代码.如果发生网络错误,该值不为0
QByteArray m_contentInByteArray;//请求到的内容
QEventLoop* m_pEventLoop;//接受内容时保持响应
volatile bool m_isFinished;
QTimer* m_timer;//定时,用于超时检测
int m_timeLimit;//用于设置超时
};
#endif // HTTPCLIENT_H
源文件:
#include "httpclient.h"
#include
#include
HttpClient::HttpClient(QObject *parent) :
QObject(parent)
{
this->m_contentInByteArray.clear();
this->m_hasNetworkError = false;
this->m_isFinished = false;
this->m_networkErrorCode = QNetworkReply::NoError;
this->m_pEventLoop = new QEventLoop(this);
this->m_pNetworkMgr = new QNetworkAccessManager(this);
this->m_pNetworkReply = NULL;
this->m_timeLimit = 60*1000;
this->m_timer = new QTimer(this);
QObject::connect( this->m_pNetworkMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(httpRequestFinished(QNetworkReply*)));
//QObject::connect( network, SIGNAL(finished(QNetworkReply*)), this, SIGNAL(finished()));
QObject::connect( this->m_timer, SIGNAL(timeout()), this, SLOT(timeOutHandler()));
}
HttpClient::~HttpClient()
{
delete this->m_pEventLoop;
this->m_pEventLoop = NULL;
delete this->m_pNetworkMgr;
this->m_pNetworkMgr = NULL;
delete this->m_timer;
this->m_timer = NULL;
}
QString HttpClient::get(QNetworkRequest &request)
{
this->m_pNetworkReply = this->m_pNetworkMgr->get(request);
QObject::connect(this->m_pNetworkReply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkErrorHandler(QNetworkReply::NetworkError)));
//计时器启动
this->m_timer->start(this->m_timeLimit);
this->m_pEventLoop->exec();
this->m_pNetworkReply->close();
delete this->m_pNetworkReply;
this->m_pNetworkReply = NULL;
if(!this->hasNetworkError())
{
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
return codec->toUnicode(this->m_contentInByteArray);
}
else
{
return QString::null;
}
}
QString HttpClient::post(QNetworkRequest &request, const QByteArray &data)
{
this->m_pNetworkReply = this->m_pNetworkMgr->post(request,data);
QObject::connect(this->m_pNetworkReply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(networkErrorHandler(QNetworkReply::NetworkError)));
//计时器启动
this->m_timer->start(this->m_timeLimit);
this->m_pEventLoop->exec();
this->m_pNetworkReply->close();
delete this->m_pNetworkReply;
this->m_pNetworkReply = NULL;
if(!this->hasNetworkError())
{
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
return codec->toUnicode(this->m_contentInByteArray);
}
else
{
return QString::null;
}
}
void HttpClient::httpRequestFinished(QNetworkReply *reply)
{
this->m_isFinished = true;
this->m_contentInByteArray = reply->readAll();
this->m_timer->stop();
this->m_pEventLoop->exit();
}
void HttpClient::timeOutHandler()
{
this->m_hasNetworkError = true;
this->m_networkErrorCode = QNetworkReply::TimeoutError;
this->m_contentInByteArray = this->m_pNetworkReply->readAll();
this->m_timer->stop();
this->m_pEventLoop->exit();
}
void HttpClient::networkErrorHandler(QNetworkReply::NetworkError error)
{
this->m_hasNetworkError = true;
this->m_networkErrorCode = error;
qDebug()<<"网络错误描述:"<m_pNetworkReply->errorString();
qDebug()<<"网络错误代码:"<m_pNetworkReply->error();
}
void HttpClient::setTimeOutLimit(int time)
{
this->m_timeLimit = time;
}
QString JsonUtil::getValueByKey(const QString &source, const QString &key)
{
QScriptEngine engine;
QScriptValue sc = engine.evaluate("value = " + source);
QScriptValueIterator it(sc);
while(it.hasNext())
{
it.next();
if (it.name().compare(key) == 0)
return it.value().toString();
}
return NULL;
}
首先看入口程序:
#include "mainwindow.h"
#include
#include "oauthdialog.h"
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec *encoding = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForTr(encoding);
QTextCodec::setCodecForLocale(encoding);
QTextCodec::setCodecForCStrings(encoding);
MainWindow w;
OauthDialog dlg(&w);
if(dlg.exec()==QDialog::Accepted)
{
QApplication::setQuitOnLastWindowClosed(true);
w.show();
return a.exec();
}
return 0;
}
#include "oauthdialog.h"
#include "ui_oauthdialog.h"
#include "httpclient.h"
#include "jsonutil.h"
#include
#include
#include
#include
OauthDialog::OauthDialog(MainWindow* main) :
main(main),
ui(new Ui::OauthDialog)
{
ui->setupUi(this);
QUrl url;//登录授权地址
url.setUrl("https://api.weibo.com/oauth2/authorize?client_id=yourid&redirect_uri=http://www.baidu.com&response_type=code");
ui->m_webView->setUrl(url);
//url变化信号,url发生变化判断是否是回调地址并截取code值
QObject::connect( ui->m_webView, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChgHandler(QUrl)) );
}
void OauthDialog::urlChgHandler(const QUrl& url)
{
QString strUrl = url.toString();
if (strUrl.contains("code="))
{
QStringList strList = strUrl.split("code=");
QString code = strList.at(1);
qDebug()<<"返回code值:"<post(request,postData);
delete http;
//qDebug()<<"content:"<main->setAccesstoken(accessToken);
this->main->setUid(uid);
this->accept();
}
}
OauthDialog::~OauthDialog()
{
delete ui;
}
下面是获取登录用户的一些基本信息的接口:
void MainWindow::initAccountInfo()
{
HttpClient *http = new HttpClient(this);
QUrl url;
url.setUrl("https://api.weibo.com/2/users/show.json");
url.addQueryItem("access_token",this->getAccesstoken());
url.addQueryItem("uid",this->getUid());
QNetworkRequest request;
request.setUrl(url);
QString ret = http->get(request);
JsonUtil json;
this->ui->m_btn_name->setText(json.getValueByKey(ret,"screen_name"));
this->ui->m_btn_attention->setText("关注:"+json.getValueByKey(ret,"friends_count"));
this->ui->m_btn_funs->setText("粉丝:"+json.getValueByKey(ret,"followers_count"));
this->ui->m_btn_weibo->setText("微博:"+json.getValueByKey(ret,"statuses_count"));
delete http;
}
void MainWindow::getWeiboId()
{
HttpClient *http = new HttpClient(this);
QUrl url;
url.setUrl("https://api.weibo.com/2/users/show.json");
url.addQueryItem("access_token",this->getAccesstoken());
url.addQueryItem("screen_name",this->ui->m_name->text());
QNetworkRequest request;
request.setUrl(url);
QString ret = http->get(request);
qDebug()<ui->m_text_ids->setText(id+name+description+weiboId + weiboContent);
delete http;
}
下面是发表评论:
void MainWindow::timerUpdate()
{
HttpClient *http = new HttpClient(this);
QUrl url;
url.setUrl("https://api.weibo.com/2/comments/create.json");
QNetworkRequest request;
request.setUrl(url);
QString content = this->ui->m_comment->document()->toPlainText();
QString weiboid = this->ui->m_weiboid->text();
QByteArray data = "access_token="+this->getAccesstoken().toAscii()+
"&comment="+QUrl::toPercentEncoding(content.toUtf8()) +
"&id="+weiboid.toAscii();
http->post(request,data);
delete http;
}
这样就可以自动发表评论了。
看一下截图:
注:评论频率不要太高了,小心被啊浪封杀!而且对普通用户,每小时的api调用次数也是有限制的。