物理超好玩

  • 首页
  • Noip学习助手
  • 书法字典APP下载
  • 资源列表
  • 格式化代码
  • 习题答案
  • 创建块
  • 关于
物理超好玩
真诚面对自己
  1. 首页
  2. 程序设计
  3. 正文

用QT开发百度文库文本下载工具

2021年01月07日 1056点热度 4人点赞 0条评论

文本目录

  • 用QT开发百度文库文本下载工具
  • 缘起
  • Visual Studio 2019配置qt开发环境
  • 界面设计
      • 精简界面
      • 使用布局管理器简化布局设计
    • QT按扭事件关联
    • 界面控件的访问
    • 访问网络
    • SSL加密访问
    • 正则表达式的使用
    • 使用QT解析Json数据
    • 最终结果
    • 软件的发布
    • 源代码下载:

用QT开发百度文库文本下载工具

花了半天时间,终于用Visual Studion 2019 + QT + C++ 写了一个百库文库文档文本的下载工具。本工具的开发,仅出自对技术的探索和研究,并不可以对百度文库付费文档进行下载,并且只能下载文本。

缘起

以前一直使用.net、java、python写些小程序,这些开发框架使用方便,开发效率都很高。但这些框架都有一个最麻烦的事情,就是需要安装一个庞大的运行库,为软件的发布造成不便。为此花了半天时间研究了Visual Studion 2019 + QT + C++的开发技术。

Visual Studio 2019配置qt开发环境

环境的配制可以参看这一篇文章:Visual Studio 2019配置qt开发环境

需要补充说明的一点,本项目需要使用QNetWork库,这需要在创建项目时进行选择,否则头文件不能引用,编译无法通过。

在创建QT Widgets Application向导程序中,到下面这一步时,一定要在Qt Modules这里点一下,在弹出的列表中选择要使用的模块。本示例需要增加选择Network模块。

q1

q2

界面设计

在生成项目的“解决方案的资源管理器”中找到后缀为.ui的文件,双击就可打开QT设计师工具。

q3

QT设计师如下图:

q4

如果设计简单的界面,下面的经验也许能够帮助你。

精简界面

简单的界面设计,不需要菜单和工具栏以及状态栏,在右上角的对象查看器中,均可以在右键菜单中删除。

使用布局管理器简化布局设计

更改最底层的centralWidget的布局管理器为垂直布局。需要注意的事:添加一个控件之后才能更改;在设计器中右键菜单最下面可看到更改布局的菜单。这样再添加的控件就会垂直分布。

若想自动水平分布,可以再添加水平布局HorizontalLayout,再向这中添加控件。

最终控件结构如下图:

q5

保存关闭QT设计师,在VS中编译运行程序,就可看到我们设计的程序。

QT按扭事件关联

为了让QT是响应事件,我们需要把点击事件和处理函数关联起来。在VS中,不能通过信号/槽编辑器来完成,至少我摸索了几分钟,没有发现可行的方法。常规的做法是用代码进行关联,但经过摸索,发现VS可以自动将事件和函数进行关联。自动关联时函数的名称必须起得符合规范,格式如下: on_控件名_clicked(),分别在头文件中声明,在cpp文件中实现就可以自动的关联起来。代码如下:

//头文件中添加

private slots:

void on_btDownload_clicked();

//cpp中添加

void QtWenKuDownloader::on_btDownload_clicked() { }

 

界面控件的访问

本示例中主要要访问两种控件,它们的访问方法,可以参看他们的类说明文件就可以了。代码如下:

//从LineEdit中获取URL

QString url = ui.leUrl->text();

//将结果添加到PlainTextEdit

ui.pteHtml->appendPlainText(html);

访问网络

前面如果钩选了NetWork模块,才可以使用网络访问功能,否则无法正常添加头文件、编译时会出现无法解析的外部符号 __declspec(dllimport的错误。

想要获取网页内容,需要添加头文件

#include <QtNetwork>

网页下载函数如下:

QByteArray HttpGet(QString url)
{
    QNetworkAccessManager manager;
    QEventLoop eventLoop;
    QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
    QNetworkRequest request;
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain; charset=utf-8");
    request.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0");
    QNetworkReply* reply = manager.get(request);
    eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
    QByteArray response;
    if (reply->error() == QNetworkReply::NoError) {
        response = reply->readAll();
    }
    else {
    }
    reply->deleteLater();
    return response;
}

 

SSL加密访问

由于百度文库的访问是通过SSL加密的,如果没有设置好,会弹出错误。解决办法如下:

下载openssl下载:http://slproweb.com/products/Win32OpenSSL.html

选择自己程序对应的版本进行安装,将openssl的bin目录下面的libcrypto-1_1-x64.dll和libssl-1_1-x64.dll库拷贝出来放到生成程序exe同级目录下即可。如果32位程序,文件名中不带x64。

正则表达式的使用

正则表达式是提取网页内容的好工具。

使用正则表达式,要包含下面的头文件:

#include <qregexp.h>

具体代码如下:

//从url中解析百度文档的ID

QString ParseDocId(QString url) {

//创建正则表达式解析对象

QRegExp re("view/([0-9a-f]{8,})\.html");

QString wndIndex;

//用正则表达式进行查找

int pos = re.indexIn(url, 0);

if (pos > 0) {

return re.cap(1);

}

else

{

return "";

}

}

 

使用QT解析Json数据

需要包含的头文件:

#include <QJsonObject>

#include <QJsonDocument>

#include <QJsonValue>

#include <QJsonArray>

示例代码如下:

QString parse_doc_content(QString content) {
    int lindex = content.indexOf('(') + 1;
    int rindex = content.lastIndexOf(')');
    QString json = content.mid(lindex, rindex - lindex);
    QJsonParseError jsonError;
    QJsonDocument parseDoc = QJsonDocument::fromJson(json.toUtf8(), &jsonError);  // 转化为 JSON 文档
    if (parseDoc.isNull() || (jsonError.error != QJsonParseError::NoError)) {
        return "解析文档出错";
    }
    QJsonArray arr = parseDoc.object().value("body").toArray();
    int size = arr.size();
    QJsonObject itm;
    QString html("");
    double last_y = 0, y;
    for (int i = 0; i < size; i++) {
        itm = arr.at(i).toObject();
        if (itm.value("t").toString().compare("word") == 0) {
            y = itm.value("p").toObject().value("y").toDouble();
            if (last_y != 0 && y - last_y > 1)
                html.append("\n");
            last_y = y;
            html.append(itm.value("c").toString());
        }
    }
    return html;
}

QString getText(QString docId) {
    QString url = "https://wenku.baidu.com/view/" + docId + ".html";
    QString html = HttpGet(url);
    QRegExp re("var pageData = ([^\n]*)");
    int pos = re.indexIn(html, 0);
    if (pos > 0) {
        QString jstr = re.cap(1);
        QJsonParseError jsonError;
        QJsonDocument parseDoc = QJsonDocument::fromJson(jstr.mid(0, jstr.length() - 1).toUtf8(), &jsonError);  // 转化为 JSON 文档
        if (parseDoc.isNull() || (jsonError.error != QJsonParseError::NoError)) {
            return "解析文档出错";
        }

        QJsonObject object = parseDoc.object();
        if (object.contains("readerInfo2019")) {
            object = object.value("readerInfo2019").toObject();
        }
        else
        {
            return "解析文档出错";
        }

        if (object.contains("htmlUrls")) {
            QString html_url_content = object.value("htmlUrls").toString();
            parseDoc = QJsonDocument::fromJson(html_url_content.toUtf8(), &jsonError);
        }
        else
        {
            return "解析文档出错";
        }
        if (parseDoc.isNull() || (jsonError.error != QJsonParseError::NoError)) {
            return "解析文档出错";
        }

        object = parseDoc.object();
        if (object.contains("json")) {
            QJsonArray arr = object.value("json").toArray();
            int size = arr.size();
            QJsonObject itm;
            QString purl;
            QString data;
            QString html("");
            for (int i = 0; i < size; i++) {
                itm = arr.at(i).toObject();
                purl = itm.value("pageLoadUrl").toString();
                data = HttpGet(purl);
                html.append(parse_doc_content(data));
            }
            return html;
        }
        else
        {
            return "解析文档出错";
        }
    }
    else
    {
        return "无法解析页面";
    }
}

 

最终结果

q6

软件的发布

Qt5程序打包发布教程(Windows版)https://blog.csdn.net/my1324/article/details/103270782

源代码下载:

Gitee源码:https://gitee.com/zizai/qt-wen-ku-downloader

https://pan.baidu.com/s/1LsNjHMAJ43yUvNiz6D066g

提取码:4jd6

百度网盘提取二维码:

845E5CDAEDAE9E3473CB0F1ADF365D35

 

相关文章:

  1. 格式混乱的百度文库复制文本格式化工具
  2. 用Python下载PHET互动仿真程序
  3. Idea中用gradle打包可执行的jar
  4. 在IDEA和Android Studio中用Gradle构建javacv开发环境
  5. IDEA用Gradle打包GUI Form为可执行的jar
  6. U盘随身便携Git http服务器

订阅号“物理超好玩”
标签: QT 下载工具 正则表达式 百度文库
最后更新:2021年01月07日

坚持

真诚的面对自己的内心。 确立志向;全力准备;清净无扰,最终成功。 尊重自我,做自己最擅长的事情,做自己最喜欢的事情。

点赞
< 上一篇
下一篇 >

坚持

真诚的面对自己的内心。 确立志向;全力准备;清净无扰,最终成功。 尊重自我,做自己最擅长的事情,做自己最喜欢的事情。

分类
  • NOIP (1)
  • 习题讲解 (9)
  • 克服沉迷 (2)
  • 游戏危害 (1)
  • 程序设计 (10)
  • 软件作品 (2)
标签聚合
初中物理 gradle 电学 串联电路 计算题 javacv Idea OpenCV
最新 热点 随机
最新 热点 随机
中国游戏防沉迷简史 转移注意力 认识游戏的危害 U盘随身便携Git http服务器 IDEA用Gradle打包GUI Form为可执行的jar 运用浮力求密度解题思路
IDEA用Gradle打包GUI Form为可执行的jar 书法字典APP下载 Idea中用gradle打包可执行的jar 认识游戏的危害 中国游戏防沉迷简史 用QT开发百度文库文本下载工具
  • 用QT开发百度文库文本下载工具
  • 缘起
  • Visual Studio 2019配置qt开发环境
  • 界面设计
      • 精简界面
      • 使用布局管理器简化布局设计
    • QT按扭事件关联
    • 界面控件的访问
    • 访问网络
    • SSL加密访问
    • 正则表达式的使用
    • 使用QT解析Json数据
    • 最终结果
    • 软件的发布
    • 源代码下载:

COPYRIGHT © 2021 物理超好玩. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

豫ICP备16037997号-2