#include "historydata.h" #include "ui_historydata.h" #include #include #include #include #include #include #include #include #include #pragma execution_character_set("utf-8") HistoryData::HistoryData(QWidget *parent) : QMainWindow(parent), ui(new Ui::HistoryData) { ui->setupUi(this); // 注册元类型 qRegisterMetaType>>("QVector>"); qRegisterMetaType>>("QVector> &"); // ui相关 ui->dateEdit->setDate(QDate::currentDate()); ui->dateEdit_2->setDate(QDate::currentDate()); m_model = new QStandardItemModel(1,9,this); m_customModel = new CustomSortProxyModel; // 可自定义排序的模型 m_customModel->setSourceModel(m_model); // 设置源模型 //ui->tableView->setModel(m_model); ui->tableView->setModel(m_customModel); // 表格列排序 ui->tableView->setSortingEnabled(true); QStringList labels; labels<<"股票名字"<<"股票代号"<<"市值(亿)"<<"涨跌幅"<<"收盘价"<<"成交额(亿)"<<"成交量"<<"换手率"<<"PE_TTM"; m_model->setHorizontalHeaderLabels(labels); initMySQL(); // 初始化MySQL // 处理数据爬取的操作 // 模拟浏览器的参数 QString userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"; m_cookie = "__utma=1.731742638.1647403301.1699341909.1700229030.32; device_id=196eef62baf016c7d95a22752d9bdbab; smidV2=20240414233939e95389ecf7ecd2f4d08524ce770aacd500753aa68e9640320; s=c611de27gr; cookiesu=651726298794778; xq_a_token=220b0abef0fac476d076c9f7a3938b7edac35f48; xqat=220b0abef0fac476d076c9f7a3938b7edac35f48; xq_r_token=1d46f0ed628506486164e5055a4993f9b54b2f4c; xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOi0xLCJpc3MiOiJ1YyIsImV4cCI6MTcyOTIxMjc4NCwiY3RtIjoxNzI3NDkwOTU3MjA0LCJjaWQiOiJkOWQwbjRBWnVwIn0.C_GmKEhTaaioDMLWkgZyMXDl4duYEVmsdJHsTi7gbcNz0Tohc-uxHsaw0yBT5k-qmbrJ_RaLMCSxy06v14-R3dwL-MsiKRHxHa5qvQZN4BjEgvPRkqqvPgE_fkPLte8qQOEgd5iVkhr-4mjip0-9WCeXYiH7DygxFOBXGlgoPtpPzAtOTm5TWJmXh0ipDsIZxfNOl8jipXYaIdkv_kqLul5gqiBi5qqnwONDa24Zx-Kvpm8ySWiPFBLzZBqTuRBs4oKAMpSdOiYGLVL7dcSDDZyWqAexmrN4f19hkmd6gBHL4dCczRMDGYc1e98sQtlbZ5lgeEuuM24jjcuwCxsxXQ; u=651726298794778; Hm_lvt_1db88642e346389874251b5a1eded6e3=1727099939,1727251802,1727488707,1727491020; HMACCOUNT=1628106D67895387; acw_tc=2760828017275244258732552e9880f861be6db0c40facbdd5f223490decc2; acw_sc__v2=66f7ee8290dc3f63112948801ef331b8c97ccb35; Hm_lpvt_1db88642e346389874251b5a1eded6e3=1727524485; .thumbcache_f24b8bbe5a5934237bbc0eda20c1b6e7=t00N841S/BEpxTGOoJrbm0blWik12om0ew/whcq/V2DNtyEA8um7J+yzeGOli+6iP/TrvrH0YKH2kHlsmDb5EQ%3D%3D; ssxmod_itna=YqAOBKYve+x0ODfxBcDB4DKM7RtAA4454DkDIEC+GAqGNK3DZDiqAPGhDC8RzeL4Ko7+e2aeQvSeopd5pYDk0Ge5TB0PIjaIDB3DEx06TCCQxiiSDCeDIDWeDiDG4Gm4qGtDpxG=DjDytZ9TtDm4GWGqDmDGYBWqDgDYQDGwIXD7QDIqtW07tQDDNQKpAKDiYeHlL5uMRMtOrK7DtDjdTD/3+kZCbCcPwVFeFO=nPcDB6wxBjZRq00Un+g4mNqLYf4IDAxQuYKtgheYYoAfDhTKhhLSGx4tGY4+GDKSiMS2DDAIvdKeD; ssxmod_itna2=YqAOBKYve+x0ODfxBcDB4DKM7RtAA4454DkDIEC+GDA69mqD/YttDFhxMltFKApT7bCMH+bytp7GQQyCbBWukeAF3+jxeN2wLjbQAFcdwbeNeoohjQ4qtEnLg4TKyX2LqVL=CGaV=GqZZqbDby8DFnFbgWiZEH8zoBzBCbzqWeqwoPq7/TpL=gIRY8sVhEpnWWHQU8sz+S8=+8oRerHq0wtQnSzyQDK7Dmvr3a+VY7fezRmxKF=bDeqexYUbuuzw2eR3In9evW6tzHbQY6vp=AIOUc9l6vc0vOl9plD6D07zGGQ41uxpii2Y5s7KvYQDWGYExD7=DYKKeD=="; QByteArray cookieByte = m_cookie.toUtf8(); QList list; list.push_back(QNetworkCookie(cookieByte)); QVariant var; var.setValue(list); // 设置要访问的网址 m_request.setUrl(QUrl("https://xueqiu.com/?md5__1038=QqGxcDnDyiitnD05o4%2Br%3Di%3De0KDtYqCDRWOoD")); // 设置请求头,用户代理,用来模拟浏览器 m_request.setHeader(QNetworkRequest::UserAgentHeader,userAgent); // 设置cookie //m_request.setHeader(QNetworkRequest::CookieHeader, var); // 查看manager都支持哪些协议 qDebug()<<"历史分析--支持的协议:"<setHorizontalHeaderLabels(poolLabel); ui->tableView_2->setModel(m_poolModel); // 股票池定时刷新 m_poolTimer = new QTimer(this); connect(m_poolTimer,SIGNAL(timeout()),this,SLOT(poolTimerSlot())); m_poolTimer->start(10*1000); m_getPoolCloseTimer = new QTimer(this); // 刷新股票池最新价格 connect(m_getPoolCloseTimer,SIGNAL(timeout()),this,SLOT(getLastCloseSlot())); } HistoryData::~HistoryData() { delete ui; } void HistoryData::initMySQL() { //添加一个数据库 db=QSqlDatabase::addDatabase("QMYSQL"); //括号内要写出数据库的类型 //设置数据库 db.setHostName("127.0.0.1"); //设置数据库的主机ip //设置数据库的用户名 db.setUserName("root"); //设置数据库的密码 db.setPassword("root"); //这个就是安装MySQL时设置的密码 //设置数据库的名字 db.setDatabaseName("stock_plan"); //打开数据库(已经安装过mysql驱动了) if(db.open()==false){ QMessageBox::warning(this,"waring",db.lastError().text()); }else{ qDebug()<<"mysql conn ok"; } } void HistoryData::on_pushButton_clicked() { QSqlQuery que(db); QString sql = "select * from stock_day_info"; if(que.exec(sql)){ qDebug()<<"select ok"; }else{ qDebug()<<"select fail"< &codeNames) { m_codeNames = codeNames; qDebug()<<"size:"<readAll(); // 将数据写到文件中,方便观察数据内容 // QFile file("data_history.txt"); // file.open(QIODevice::ReadWrite | QIODevice::Text); // QTextStream out(&file); // out << buffer << endl; // file.close(); // 下面使用JSON进行数据处理 if(reply->url().toString().indexOf("https://xueqiu.com/") != -1){ qDebug()<<"发现首页url"; qDebug()<url().toString().indexOf("https://stock.xueqiu.com/v5/stock/chart/kline.json") != -1){ qDebug()<<"查看个股情况:"; getOneStock(buffer); }else if(reply->url().toString().indexOf("https://hqm.stock.sohu.com/getqjson") != -1){ qDebug()<<"获取股票池个股价格"; getPoolStock(buffer); } } /* {"data":{"symbol":"SZ301633","column": ["timestamp","volume","open","high","low","close","chg","percent","turnoverrate","amount","volume_post","amount_post","ma5","ma10","ma20","ma30","pe","market_capital"], "item":[[1730908800000,10787401,187.0,187.0,133.1,137.13,99.19,261.44,77.5,1.608757505E9,1300,178269.0,null,null,null,null,67.0447,7.6353984E9], [1730995200000,8348116,145.8,158.5,130.06,132.9,-4.23,-3.08,59.97,1.19303472E9,1000,132900.0,null,null,null,null,64.9765,7.399872E9], */ void HistoryData::getOneStock(QByteArray &buffer) { QJsonDocument jd = QJsonDocument::fromJson(buffer); if(jd.isObject()){ QJsonObject jObject = jd.object(); QJsonArray jArr = jObject.value("data").toObject().value("item").toArray(); // 通过键值对取值 int cnt = jArr.count(); qDebug()<<"数组size:"< tmp = buffer.split('['); //qDebug()<<"[ tmp size:"< row = tmp.at(i).split(','); if(row.size() > 2){ QString code = QString::fromLocal8Bit(row.at(0).mid(1,row.at(0).size()-2)).trimmed().split('_').at(1); QString name = QString::fromLocal8Bit(row.at(1).mid(1,row.at(1).size()-2)).trimmed(); double close = row.at(2).mid(1,row.at(2).size()-2).toDouble(); //qDebug()<statusbar->showMessage("查询中...请耐心等待结果..."); QString searchTime = ui->dateEdit->text(); qDebug()<<"查询的时间:"<setRowCount(0); // 重置模型行数 int rows = 0; while (que.next()) { QString name = que.value(0).toString(); QString code = que.value(1).toString(); QString market_capital = QString::number(que.value(2).toDouble()/100000000); QString percent = que.value(3).toString(); QString close = que.value(4).toString(); QString amount = QString::number(que.value(5).toDouble()/100000000); QString volume = que.value(6).toString(); QString turnover_rate = que.value(7).toString(); QString pe_ttm = que.value(8).toString(); m_modelDatas.append({name,code,market_capital,percent,close,amount,volume,turnover_rate,pe_ttm}); QList items; items.append(new QStandardItem(name)); items.append(new QStandardItem(code)); items.append(new QStandardItem(market_capital)); //items.append(new QStandardItem(percent)); QStandardItem *percentItem = new QStandardItem(percent); if(percent.toDouble() > 0){ percentItem->setData(QColor("red"),Qt::DecorationRole); // 添加一个装饰的颜色为红色 percentItem->setData(QColor("red"),Qt::TextColorRole); // 将字体颜色设置为红色 items.at(0)->setData(QColor("red"),Qt::TextColorRole); // 将股票名字设置为红色 } else if(percent.toDouble() < 0){ percentItem->setData(QColor("green"),Qt::BackgroundColorRole); items.at(0)->setData(QColor("green"),Qt::TextColorRole); } items.append(percentItem); items.append(new QStandardItem(close)); items.append(new QStandardItem(amount)); items.append(new QStandardItem(volume)); items.append(new QStandardItem(turnover_rate)); items.append(new QStandardItem(pe_ttm)); m_model->appendRow(items); rows++; } qDebug()<<"查询到行数:"<statusbar->showMessage(QString("耗时:%1 毫秒,查询完成.").arg(QString::number(need)),10*1000); ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); //emit sendHistoryModel(m_modelDatas); // 给信息展示发模型 ui->textBrowser->append(QString("查询日期:%1 耗时: %2 毫秒 查到条数:%3").arg(searchTime).arg(QString::number(need)).arg(QString::number(m_model->rowCount()))); } void HistoryData::on_pushButton_2_clicked() { //emit sendHistoryModel(m_modelDatas); // 给信息展示发模型 emit sendHistoryModel(m_model); } void HistoryData::on_pushButton_addStock_clicked() { QString name = ui->lineEdit->text(); QString code = ui->lineEdit_2->text(); QString price = ui->lineEdit_3->text(); QString in_date = ui->dateEdit_2->text(); QString type = ui->comboBox->currentText(); qDebug()<setRowCount(0); while (que.next()) { QList items; for(int i=0;i<10;++i){ QString item = que.value(i).toString(); QStandardItem *it = new QStandardItem(item); if(i==6){ if(item.toDouble() > 0){ it->setData(QColor("red"),Qt::DecorationRole); // 添加一个装饰的颜色为红色 it->setData(QColor("red"),Qt::TextColorRole); // 将字体颜色设置为红色 items.at(1)->setData(QColor("red"),Qt::TextColorRole); // 将股票名字设置为红色 }else if(item.toDouble() < 0){ it->setData(QColor("green"),Qt::BackgroundColorRole); items.at(1)->setData(QColor("green"),Qt::TextColorRole); } } items.append(it); } m_poolModel->appendRow(items); // 整行添加 效率更高 } }else{ qDebug()<<"select fail"; } m_poolTimer->setInterval(60*1000); } void HistoryData::on_checkBox_clicked() { QString dt = "2025-02-10"; QString sql = "select log_time from days_info order by log_time desc"; QSqlQuery que(db); if(que.exec(sql)){ if (que.next()) { dt = que.value(0).toString(); }else{ qDebug()<<"查询结果集为空"; return; } }else{ qDebug()<<"查询失败"; return ; } if(ui->checkBox->isChecked()){ ui->pushButton_update->setEnabled(true); }else{ ui->pushButton_update->setEnabled(false); } QDate d1 = QDate::fromString(dt,"yyyy-MM-dd"); QDate d2 = QDate::currentDate(); int days = 0; // 经过了多少个周内的天数 for(QDate begin = d1.addDays(1);begin <= d2;begin = begin.addDays(1)){ if(begin.dayOfWeek() != Qt::Saturday && begin.dayOfWeek() != Qt::Sunday){ days++; } } qDebug()<<"days:"<rowCount();++i){ if(m_poolModel->item(i,2)){ QString code="cn_"; if(i > 0) code = ",cn_"; code += m_poolModel->item(i,2)->text().mid(2); // qDebug()<<"code:"<checkBox_updatePoolClose->isChecked()){ m_getPoolCloseTimer->start(3*60*1000); // 3分钟更新一次 }else{ m_getPoolCloseTimer->stop(); } }