物理超好玩

  • 首页
  • 书法字典APP下载
  • 资源列表
  • 关于
反游戏沉迷
真诚面对自己
  1. 首页
  2. 程序设计
  3. 正文

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

2021年01月07日 642点热度 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)
标签聚合
Idea javacv gradle 计算题 串联电路 百度文库 电学 初中物理
最新 热点 随机
最新 热点 随机
中国游戏防沉迷简史 转移注意力 认识游戏的危害 U盘随身便携Git http服务器 IDEA用Gradle打包GUI Form为可执行的jar 运用浮力求密度解题思路
初中物理电学计算题第四讲:数据挖掘 初中物理电学计算题第三讲:串联电路电流电阻极值推理实例 在IDEA和Android Studio中用Gradle构建javacv开发环境 在JavaCV中合并两个Mat 书法字典APP下载 初中物理识别电路图、画电路图的方法
  • 用QT开发百度文库文本下载工具
  • 缘起
  • Visual Studio 2019配置qt开发环境
  • 界面设计
      • 精简界面
      • 使用布局管理器简化布局设计
    • QT按扭事件关联
    • 界面控件的访问
    • 访问网络
    • SSL加密访问
    • 正则表达式的使用
    • 使用QT解析Json数据
    • 最终结果
    • 软件的发布
    • 源代码下载:

COPYRIGHT © 2021 反游戏沉迷. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

豫ICP备16037997号-2