新浪微博开放平台研究-实现微博自动评论(下)
2013-11-28 22:44
453 查看
源码下载
调用新浪微博开放接口,首先要到新浪服务器进行认证,新浪微博目前采用的是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请求帮助类,挺好用的,源码如下:
头文件:
微博接口返回的是json格式,意味着需要json解析,Qt自带一个QScriptEngine,可以用来解析简单的json,但貌似解析不了两层以上的json,没有仔细研究,先凑合着用:
用到的工具类都准备好了,下面进入正题。
首先看入口程序:
MainWindow是主窗口类,QauthDialog是授权对话框,首先在授权对话框进行登录授权等。
上面代码获取到了access token,以后带着这个就可以访问其它接口了。
下面是获取登录用户的一些基本信息的接口:
要想评论某条微博,首先要获取这个微博的id,试了一下获取指定用户的微博的api,不知道为什么返回来的是空,又试了一下获取指定用户的用户信息的接口,返回的内容正好包含用户最新的一条微博信息,正好用这个api做实验吧。
用户信息api返回的json信息包含两层,Qt自带的json解析类貌似解析不了,上面代码用QString的split硬生生的把想要的信息分隔了出来,网上有很多c++的开源json工具,这里就不搞那么复杂了。
下面是发表评论:
用了QTimer定时器,按照指定频率执行timerUpdate函数。
这样就可以自动发表评论了。
看一下截图:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/568cdbc3bd2bc33bb7a3ae5545ffc966)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/dea4a93a77f3a0db131742d3bca2f5ab)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201911/15/1291fc82a75cefac0e2e194196b54a0c)
注:评论频率不要太高了,小心被啊浪封杀!而且对普通用户,每小时的api调用次数也是有限制的。
调用新浪微博开放接口,首先要到新浪服务器进行认证,新浪微博目前采用的是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 <QObject> #include <QNetworkReply> #include <QNetworkAccessManager> #include <QNetworkRequest> #include <QEventLoop> #include <QTimer> 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 <QTextCodec> #include <QDebug> 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()<<"网络错误描述:"<<this->m_pNetworkReply->errorString(); qDebug()<<"网络错误代码:"<<this->m_pNetworkReply->error(); } void HttpClient::setTimeOutLimit(int time) { this->m_timeLimit = time; }
微博接口返回的是json格式,意味着需要json解析,Qt自带一个QScriptEngine,可以用来解析简单的json,但貌似解析不了两层以上的json,没有仔细研究,先凑合着用:
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 <QApplication> #include "oauthdialog.h" #include <QTextCodec> #include <QDebug> 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; }
MainWindow是主窗口类,QauthDialog是授权对话框,首先在授权对话框进行登录授权等。
#include "oauthdialog.h" #include "ui_oauthdialog.h" #include "httpclient.h" #include "jsonutil.h" #include <QUrl> #include <QDebug> #include <QMessageBox> #include <mainwindow.h> 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值:"<<code; QString strAtUrl = "https://api.weibo.com/oauth2/access_token"; QByteArray postData = "client_id=yourid&client_secret=yoursecret&grant_type=authorization_code&code=" + code.toAscii() +"&redirect_uri=http://www.baidu.com"; HttpClient* http = new HttpClient(); QUrl atUrl; atUrl.setUrl(strAtUrl); QNetworkRequest request; request.setUrl(atUrl); QString content = http->post(request,postData); delete http; //qDebug()<<"content:"<<content; JsonUtil json; QString accessToken = json.getValueByKey(content,"access_token"); QString uid = json.getValueByKey(content,"uid"); qDebug()<<"accessToken:"<<accessToken; qDebug()<<"uid:"<<uid; this->main->setAccesstoken(accessToken); this->main->setUid(uid); this->accept(); } } OauthDialog::~OauthDialog() { delete ui; }
上面代码获取到了access token,以后带着这个就可以访问其它接口了。
下面是获取登录用户的一些基本信息的接口:
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; }
要想评论某条微博,首先要获取这个微博的id,试了一下获取指定用户的微博的api,不知道为什么返回来的是空,又试了一下获取指定用户的用户信息的接口,返回的内容正好包含用户最新的一条微博信息,正好用这个api做实验吧。
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()<<ret; JsonUtil json; QString id = "id:\n"+json.getValueByKey(ret,"id")+"\n"; QString name = "name:\n"+json.getValueByKey(ret,"screen_name")+"\n"; QString description = "description:\n"+json.getValueByKey(ret,"description")+"\n"; QStringList list = ret.split("idstr\":\""); QString temp = list.at(2); QStringList tempList = temp.split("\",\"text\":\""); QString weiboId = "weiboId:\n"+tempList.at(0)+"\n"; QString weiboContent = "weiboContent:\n"+tempList.at(1).split("\",\"source\"").at(0)+"\n"; this->ui->m_text_ids->setText(id+name+description+weiboId + weiboContent); delete http; }
用户信息api返回的json信息包含两层,Qt自带的json解析类貌似解析不了,上面代码用QString的split硬生生的把想要的信息分隔了出来,网上有很多c++的开源json工具,这里就不搞那么复杂了。
下面是发表评论:
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; }
用了QTimer定时器,按照指定频率执行timerUpdate函数。
这样就可以自动发表评论了。
看一下截图:
注:评论频率不要太高了,小心被啊浪封杀!而且对普通用户,每小时的api调用次数也是有限制的。
相关文章推荐
- 新浪微博开放平台研究-实现微博自动评论(上)
- 基于PNP自动映射分区的安全USB技术研究与实现
- 纯代码实现WordPress评论回复自动添加@评论者的功能
- Python脚本实现自动发带图的微博
- Atitit qzone qq空间博客自动点赞与评论工具的设计与实现
- jQuery插件实现新浪微博自动底部加载
- 微博无刷新评论功能实现案例
- jquery 仿微博实现内容自动向下滚动加载
- 实现了sina微博的自动登录和发送微博功能
- Atitit qzone qq空间博客自动点赞与评论工具的设计与实现
- Python脚本实现自动发带图的微博
- Laravel5.1 实现第三方登录认证(包括微博、QQ、微信、豆瓣) 2017-01-08 18:08 457人阅读 评论(0) 收藏 举报 分类: laravel框架(33) 目录(?)[
- Atitit qzone qq空间博客自动点赞与评论工具的设计与实现
- 网站自动刷帖,刷赞,刷评论等网络推广方式的基本实现
- 基于DirectShow的MPEG-4视频传输系统的研究与实现 分类: VC++ DirectX 2013-11-09 09:40 630人阅读 评论(0) 收藏
- 研究与实现Java编程题自动评分技术的
- 基于微信红包插件的原理实现android任何APP自动发送评论(已开源)
- 关于新浪微博开放平台微博登录授权后再次登录会自动登录问题的解决办法
- iOS如何实现 回复评论自动添加@评论
- 【项目研究】自动安装并配置ODBC的思路与实现