Qt开发之HTTP

这篇文章将给大家演示QT网络编程在HTTP中的应用,用来爬取网页内容或者下载文件.我用过在三种语言是来爬取网页内容,用C语言我写了100行代码,用C++写10行代码,用Python写了两行代码.大家从这个可以看出编程的效率,但是同时带来一个问题,程序的运行效率是C>--C++>--Python  .

HTTP在C++中有一个QtNetwork类,最常用的两个函数是QNetworkAccessManager和QNetworkReply.在代码中可以post参数,可以设置代理,本文只实现了网页的下载,其他内容大家可以参考帮助文档,学习QT应该学会看QT Assistant.


新建一个Qt Gui应用,项目名称为myHTTP.其他保持默认即可,在工程文件中添加QT       += network表示支持网络库


mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QUrl>
#include <QFile>
#include <QTextStream>

class QFile;
class QNetworkReply;
class QNetworkAccessManager;

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void startRequest(QUrl url);

    void SaveFile(QString string,QString path)
        {
            QFile file(path);
            if(!file.open(QIODevice::WriteOnly | QIODevice::Append)) return ;
            QTextStream out(&file);
            out << string <<endl;
            file.close();
        }


private slots:
    void httpFinished();
    void httpReadyRead();
    void updateDataReadProgress(qint64, qint64);

    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    QNetworkAccessManager *manager;
    QNetworkReply *reply;
    QUrl url;
    QFile *file;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork>
#include <QTextCodec>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    manager = new QNetworkAccessManager(this);
    ui->progressBar->hide();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::startRequest(QUrl url)
{
    reply = manager->get(QNetworkRequest(url));
    connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));

    connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
            this, SLOT(updateDataReadProgress(qint64,qint64)));

    connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
}

void MainWindow::httpReadyRead()
{
    /* 不能调用两次reply->readAll(),第二次就会读取的数据为空 */
    //if (file) file->write(reply->readAll());
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QString string = ui->lineEdit_2->text();

    QString all = codec->toUnicode(reply->readAll());

    SaveFile(all,string);
}


void MainWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
{
    ui->progressBar->setMaximum(totalBytes);
    ui->progressBar->setValue(bytesRead);
}

void MainWindow::httpFinished()
{
    ui->progressBar->hide();
    file->flush();
    file->close();
    reply->deleteLater();
    reply = 0;
    delete file;
    file = 0;
}

void MainWindow::on_pushButton_clicked()
{
    url = ui->lineEdit->text();
    QFileInfo info(url.path());

    qDebug() << "url.path()=" << url.path();
    QString fileName(info.fileName());
    if (fileName.isEmpty())
    {
        fileName = "index.html";
        qDebug() << "File Name is Empty!,default filename is index.html";
    }

    file = new QFile(fileName);
    if(!file->open(QIODevice::WriteOnly))
    {
        qDebug() << "file open error";
        delete file;
        file = 0;
        return;
    }
    startRequest(url);
    ui->progressBar->setValue(0);
    ui->progressBar->show();
}

main.cpp就不用贴了吧,默认即可,就是创建了一个MainWindow的对象,然后显示MainWindow.show(),然后爬取的内容就以html格式保存到工程路径下面了,大家可以指定路径的.


mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>30</x>
      <y>40</y>
      <width>101</width>
      <height>21</height>
     </rect>
    </property>
    <property name="text">
     <string>下载URL地址:</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="lineEdit">
    <property name="geometry">
     <rect>
      <x>30</x>
      <y>70</y>
      <width>321</width>
      <height>31</height>
     </rect>
    </property>
   </widget>
   <widget class="QProgressBar" name="progressBar">
    <property name="geometry">
     <rect>
      <x>30</x>
      <y>120</y>
      <width>361</width>
      <height>22</height>
     </rect>
    </property>
    <property name="value">
     <number>24</number>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>320</x>
      <y>180</y>
      <width>51</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>下载</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="lineEdit_2">
    <property name="geometry">
     <rect>
      <x>70</x>
      <y>181</y>
      <width>251</width>
      <height>24</height>
     </rect>
    </property>
    <property name="text">
     <string>/home/linux/Linux_Google.html</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_2">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>181</y>
      <width>51</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>文件路径</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>


程序运行效果如下:


大家可以在上面代码中添加代理和post参数,我就不每个都做测试了.


                                                                                                                文章出自:Linux_Google

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页