欢迎关注公众号可以查看更多完整文章
QT实现CSDN上传资源管理助手Demo之(2)模拟登录CSDN网站
在登录页面抓包分析Http请求协议内容可以得到具体细节:可以得到请求的网址,请求的方法(POST或者Get)、协议内容、请求成功后的跳转路径、请求的附加参数,如下图所示:
从附加的请求参数子串可以看到除了账号和密码外,还有三个字段:lt、execution、_eventId,其中_eventId是固定的,而前两个则是动态的。这应该是请求所需要的通行证吧。为了获取这两个字段,我们去查看一下网页源码,果然是有的:
那么我们可以解析网页内容得到,最简单的方法就是正则表达式了。正则表达式稍微研究了一下,以前觉得一团糟,仔细研究了一会,觉得没有想象中那么复杂,自己就按照规则简单写了一下匹配表达式,可能没有那么正规,但也可以获取到想要的数据了。
//正则匹配
QRegExp rep("LT-[\\w-]{1,100}");//LT-[A-Za-z0-9-]{1,100}也可以匹配
rep.indexIn(strReply);
mStringLT = rep.cap(0);
rep.setPattern("name=\"execution\" value=\"[\\w]{4,4}");
rep.indexIn(strReply);
mStringExecution = rep.cap(0).remove("name=\"execution\" value=\"");
请求部分是使用QT的NetWork模块来完成的,主要由QNetworkAccessManager来进行请求的操作。QNetworkReply来获取请求的结果,并进行必要的处理。
首先需要请求登录页面,请求的网址为:http://passport.csdn.net/account/login?from=http://my.csdn.net/my/mycsdn,从返回结果中获取通行证字段lt、execution等信息,并保存Cookies用于接下来的登录操作。
void QtResourceAssistant::initLoginParameter()
{
mNetworkAccessManager = new QNetworkAccessManager(this);
connect(mNetworkAccessManager, &QNetworkAccessManager::finished, this, &QtResourceAssistant::initLoginReply);
mNetworkAccessManager->get(QNetworkRequest(QUrl("http://passport.csdn.net/account/login?from=http://my.csdn.net/my/mycsdn")));
}
void QtResourceAssistant::initLoginReply(QNetworkReply *Reply)
{
if (Reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200)
{
QMessageBox::warning(this, tr("警告"), tr("获取网页信息失败,请检查网络并重启软件"),QMessageBox::StandardButton::Close);
return;
}
QString strReply = Reply->readAll();
Reply->deleteLater();
//正则匹配
QRegExp rep("LT-[\\w-]{1,100}");//LT-[A-Za-z0-9-]{1,100}也可以匹配
rep.indexIn(strReply);
mStringLT = rep.cap(0);
rep.setPattern("name=\"execution\" value=\"[\\w]{4,4}");
rep.indexIn(strReply);
mStringExecution = rep.cap(0).remove("name=\"execution\" value=\"");
mCookies = Reply->rawHeader("Set-Cookie");
disconnect(mNetworkAccessManager, &QNetworkAccessManager::finished, this, &QtResourceAssistant::initLoginReply);
}
预登录的信息已经拿到,接下来就要进行登录请求了。使用POST方法,需要填写请求的Header,以及链接的拼接:
void QtResourceAssistant::loginRequest()
{
QString Account = mLoginDialog.getAccount();
QString Password = mLoginDialog.getPassword();
if (Account.isEmpty() || Password.isEmpty())
return;
mWaitDialog.setText("正在登录,请稍后...");
connect(mNetworkAccessManager, &QNetworkAccessManager::finished, this, &QtResourceAssistant::loginReply);
QNetworkRequest NetworkRequest(QUrl("http://passport.csdn.net/account/login?ref=toolbar"));
NetworkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
NetworkRequest.setRawHeader(QByteArray("Referer"), QByteArray("http://download.csdn.net/?ref=toolbar"));
NetworkRequest.setRawHeader(QByteArray("Cookie"), mCookies.toLatin1());
QString strPost = "username=" + Account + "&password=" + Password + "<=" + mStringLT + "&execution=" + mStringExecution + "&_eventId=submit";
mNetworkAccessManager->post(NetworkRequest, strPost.toLatin1());
}
请求完成后,依据返回结果解析用户信息,并保存新的Cookies,作为后续请求的通行证:
void QtResourceAssistant::loginReply(QNetworkReply *Reply)
{
mWaitDialog.hide();
QString strReply = Reply->readAll();
Reply->deleteLater();
QRegExp rep("var data = \\{.+(\"\\})");
rep.indexIn(strReply);
QString strJson = rep.cap(0);
if (strJson.isEmpty())
{
QMessageBox::warning(this, tr("警告"), tr("登录失败,请检查网络并重启软件"), QMessageBox::StandardButton::Close);
return;
}
strJson = strJson.remove("var data = {").remove("}");
mUserInfoDialog.setUserInfo(strJson);//解析用户信息
mCookies = Reply->rawHeader("Set-Cookie");
mLoginSuccess = true;
disconnect(mNetworkAccessManager, &QNetworkAccessManager::finished, this, &QtResourceAssistant::loginReply);
downloadInfoRequest(1);
}
解析得到的用户信息如下图:
声明:
交流QQ:1245178753