QT5(15)模拟登陆百度

代码

一、流程

  1. 获取BaiDuID(http://yun.baidu.com/
  2. 获取token(https://passport.baidu.com/v2/api/?getapi&tpl=netdisk&apiver=v3
  3. 完成登录。如果cookie里有BaiDuSS登录成功。
  4. 好像如果要获取百度云数据还需要从其他链接更新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 &num;
//            }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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值