一、流程
- 获取BaiDuID(http://yun.baidu.com/)
- 获取token(https://passport.baidu.com/v2/api/?getapi&tpl=netdisk&apiver=v3)
- 完成登录。如果cookie里有BaiDuSS登录成功。
- 好像如果要获取百度云数据还需要从其他链接更新cookie。
许多教程里有获取gid,UBI等数据,经测试后不是一定需要。至于百度账户的验证码有时需要有时不需要,下面代码中也有。
二、代码
http类:
#ifndef ACCESSHTTP_H
#define ACCESSHTTP_H
#include <QString>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <QNetworkCookieJar>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
#include <QJsonDocument>
typedef QPair<QByteArray,QList<QNetworkCookie> > HTTPBACK;
typedef QMap<QByteArray,QByteArray> MAPBYTE;
//继承QNetworkCookieJar是为了使用其protected函数allCookies
class AccessHttp:public QNetworkCookieJar
{
private:
QString url,name,pass;
QString cookie;
public:
AccessHttp(QString,QString,QString);
AccessHttp();
~AccessHttp();
static HTTPBACK get(QString url, QList<QNetworkCookie> cookies = QList<QNetworkCookie>(), MAPBYTE headers = MAPBYTE());
static HTTPBACK post(QString url, QByteArray postData, QList<QNetworkCookie> cookies = QList<QNetworkCookie>(), MAPBYTE headers = MAPBYTE());
static QJsonObject getJsonObj(QByteArray);
};
#endif // ACCESSHTTP_H
#include "accesshttp.h"
#include <QString>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <QNetworkCookie>
#include <QNetworkCookieJar>
#include <QEventLoop>
#include <QByteArray>
#include <QList>
#include <QPair>
#include <QMap>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
typedef QPair<QByteArray,QList<QNetworkCookie> > HTTPBACK;
typedef QMap<QByteArray,QByteArray> MAPBYTE;
AccessHttp::AccessHttp(QString furl, QString fname, QString fpass)
{
url = furl;
name = fname;
pass = fpass;
}
AccessHttp::AccessHttp()
{
}
AccessHttp::~AccessHttp(){
}
HTTPBACK AccessHttp::get(QString url, QList<QNetworkCookie> insertCookies, MAPBYTE headers){
QEventLoop loop;
// 为后期获取cookie
AccessHttp netCookies;
if(!insertCookies.isEmpty()){
netCookies.setAllCookies(insertCookies);
}
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request;
request.setUrl(url);
for(MAPBYTE::iterator it = headers.begin(); it != headers.end(); it++){
request.setRawHeader(it.key(), it.value());
}
manager -> setCookieJar(&netCookies);
QNetworkReply *reply = manager -> get(request);
// qt的http是异步的,为完成同步,使用子事件循环。当完成信息获取,退出子事件。
QObject::connect(reply,SIGNAL(finished()),&loop,SLOT(quit()));
loop.exec();
QByteArray con = reply -> readAll();
QList<QNetworkCookie> cookies = netCookies.allCookies();
return HTTPBACK(con,cookies);
}
HTTPBACK AccessHttp::post(QString url, QByteArray postData, QList<QNetworkCookie> insertCookie, MAPBYTE headers){
QEventLoop loop;
// 为后期获取cookie
AccessHttp netCookies;
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request;
request.setUrl(QUrl(url));
for(MAPBYTE::iterator it = headers.begin(); it != headers.end(); it++){
request.setRawHeader(it.key(), it.value());
}
netCookies.setAllCookies(insertCookie);
manager -> setCookieJar(&netCookies);
QNetworkReply *reply = manager -> post(request,postData);
// qt的http是异步的,为完成同步,使用子事件循环。当完成信息获取,退出子事件。
QObject::connect(reply,SIGNAL(finished()),&loop,SLOT(quit()));
loop.exec();
QByteArray con = reply -> readAll();
QList<QNetworkCookie> cookies = netCookies.allCookies();
return HTTPBACK(con,cookies);
}
QJsonObject AccessHttp::getJsonObj(QByteArray fromJson){
QJsonParseError jsonError;
QJsonObject obj;
QJsonDocument jsonDoc = QJsonDocument::fromJson(fromJson, &jsonError);
if(jsonError.error == QJsonParseError::NoError){
if(jsonDoc.isObject()){
obj = jsonDoc.object();
// if(!vecKey.isEmpty()){
// for(QVector<QString>::iterator it = vecKey.begin(); it != vecKey.end()-1; it++){
// if(obj.contains(*it)){
// obj = obj.take(*it).toObject();
// qDebug()<<obj;
// }
// }
// QJsonValue value = obj.take(*(vecKey.end()-1));
// if(value.isString())
// str = value.toString();
// return &str;
// if(value.isDouble())
// num = value.toVariant().toInt();
// return #
// }else{
// return &obj;
// }
}/*else if(jsonDoc.isArray()){
arr = jsonDoc.array();
return &arr;
}*/
}else{
qDebug()<<jsonError.error;
}
return obj;
}
流程:
VECPAIR *vecPairUsers;
QString urlBaiDuIndex = "http://yun.baidu.com/";
QString urlBaiDuUBI = "https://passport.baidu.com/v2/api/?login";
QString urlBaiDuToken = "https://passport.baidu.com/v2/api/?getapi&tpl=netdisk&apiver=v3";
QString urlBaiDuLogin = "https://passport.baidu.com/v2/api/?login";
QString urlBaiDuImage = "https://passport.baidu.com/cgi-bin/genimage";
QString name = vecPairUsers->at(index).first;
QString pass = vecPairUsers->at(index).second;
// 获取BAIDUID
HTTPBACK duIndex = AccessHttp::get(urlBaiDuIndex);
// 获取UBI
// HTTPBACK duUBI = AccessHttp::get(urlBaiDuUBI, duIndex.second);
// 获取token
HTTPBACK duToken = AccessHttp::get(urlBaiDuToken, duIndex.second);
// 匹配Token
QRegExp re("\"token\" : \"([A-Za-z0-9]*)\",");
QString duRes = duToken.first;
duRes.indexOf(re);
QString token = re.cap(1);
headers["content-type"] = "application/x-www-form-urlencoded";
headers["Host"] = "passport.baidu.com";
headers["User-Agent"] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36";
headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
headers["Accept-Language"] = "zh-CN,zh;q=0.8";
// 设置gzip后需要使用zlib模块解析
// headers["Accept-Encoding"] = "gzip, deflate, br";
headers["Referer"] = "http://yun.baidu.com/";
headers["Origin"] = "http://yun.baidu.com";
// QString postData = "staticpage=http://pan.baidu.com/res/static/thirdparty/pass_v3_jump.html&charset=utf-8&token="+ token+"&tpl=netdisk&apiver=v3&tt=1392637410384&codestring=&safeflg=0&u=https://pan.baidu.com/disk/home&isPhone=false&detect=1&quick_user=0&loginmerge=true&logintype=basicLogin&username="+ name +"&password="+ pass +"&verifycode=&mem_pass=on&ppui_logintime=49586&callback=parent.bd__pcbs__hksq59";
// 获取codeString
// HTTPBACK postCod = AccessHttp::post(urlBaiDuLogin, postData.toUtf8(), duToken.second, headers);
// 匹配codeString
// QRegExp reCod("&codeString=(.*)&userName");
// QString codRes = postCod.first;
// codRes.indexOf(reCod);
// QString codeString = reCod.cap(1);
// 获取验证码图片
// QString codeImage = urlBaiDuImage +"?" + codeString;
// HTTPBACK duImage = AccessHttp::get(codeImage, postCod.second, headers);
// QPixmap pixmap;
// pixmap.loadFromData(duImage.first);
// 对话框首先阻塞运行,当用户确认输入后首先获取输入框值,再关闭对话框,返回获取到的值,再删除对话框。
// 关于获取对话框的返回值,一种是调用对话框返回函数;另一种直接传递个地址变量。
// ShowVerycode *dialogImg = new ShowVerycode(pixmap);
// connect(dialogImg->confirm, SIGNAL(clicked(bool)), dialogImg, SLOT(close()));
// dialogImg -> exec();//阻塞的 //dialogImg.show(); 非阻塞的
// QString codeDO = dialogImg -> returnCode();
// while(codeDO.isEmpty()){
// codeDO = dialogImg -> returnCode();
// }
// delete dialogImg;
// QString postDataAga = QString("staticpage=http://yun.baidu.com/res/static/thirdparty/pass_v3_jump.html&charset=utf-8&token=%1&tpl=netdisk&subpro=netdisk_web&apiver=v3&tt=1482754960334&codestring=%2&safeflg=0&u=http://yun.baidu.com/disk/home&isPhone=false&detect=1&gid=2A9AD34-8768-4053-94C4-9C37DE9888FD&quick_user=0&logintype=basicLogin&logLoginType=pc_loginBasic&idc=&loginmerge=true&foreignusername=&username=%3&password=%4&mem_pass=on&ppui_logintime=385975&countrycode=%5&callback=parent.bd__pcbs__87557").arg(token, codeString, name, pass, codeDO);
QString postDataAga = QString("staticpage=http://yun.baidu.com/res/static/thirdparty/pass_v3_jump.html&charset=utf-8&token=%1&tpl=netdisk&subpro=netdisk_web&apiver=v3&tt=1482754960334&codestring=&safeflg=0&u=http://yun.baidu.com/disk/home&isPhone=false&detect=1&gid=2A9AD34-8768-4053-94C4-9C37DE9888FD&quick_user=0&logintype=basicLogin&logLoginType=pc_loginBasic&idc=&loginmerge=true&foreignusername=&username=%2&password=%3&mem_pass=on&ppui_logintime=385975&countrycode=&callback=parent.bd__pcbs__87557").arg(token, name, pass);
// 获取成功登录cookie
HTTPBACK postLoginSuccessBaiDu = AccessHttp::post(urlBaiDuLogin, postDataAga.toUtf8(), duToken.second, headers);
qDebug()<<postLoginSuccessBaiDu.second<<"77777777777777"<<endl;
qDebug()<<postLoginSuccessBaiDu.first<<"8888888888888"<<endl;