用Qt写爬虫爬https网站图片

前置技术:QT、爬虫基础、https(ssl证书)了解

爬虫是一种将网页上所需元素总结分类下载到本地的技术,它可以模拟人的操作爬取网页中的文字和图片,一般爬虫采用Python语言编写,不过Qt也是可以写爬虫的。
一般Qt的教学书籍中都会有下载http网页的例子,Qcreater中也有http案例代码,不过一般现在的网站都为https加密网站,爬取https网站需要加一步操作。

本案例为以下界面,可以实现下载https网站源代码并储存到文本文件中,通过正则表达式寻找源代码中所需要的的内容,通过URL批量下载目标图片。


好,让我们开始。
 

1. 保证Qt可以对https网站进行操作


Qt默认是无法对https网站进行请求的,用请求http的方式下载https网站没有数据,在pro文件中添加 Qt += network,在初始程序中加入

 QNetworkAccessManager *manager = new QNetworkAccessManager(this);
 qDebug() << manager->supportedSchemes();

运行后会在输出界面显示

没有https说明你的qt不能请求https网站

对此我们需要下载openSSL来实现qt对https的请求,openSSL的网站为http://slproweb.com/products/Win32OpenSSL.html

下载对应的exe,注意要对应你的Qt的64/32位,下Light版本的就可以
安装时选择The OpenSSL binaries(/bin)directory

安装完后在OpenSSL-Win64(32) / bin文件夹中找到以下两个文件

也可以在我的下载文件中找到

将它们复制到qt执行后debug文件(有exe的那个文件)之后在运行会发现输出界面显示

有了https,说明你的Qt已经可以请求https网站了,恭喜第一步完成。

2. 下载https网站源码并放到txt文件夹



这一步分为得到源码和存入txt文件两部,我将代码写在一个按钮槽函数中

void Widget::on_btnOpenUrl_clicked()
{
    //网页地址
        const QString URLSTR =ui->lineEditURL->text();
    //储存网页代码的文件
        const QString FILE_NAME = ui->lineEditFileName->text();
        QUrl url(URLSTR); 
        QNetworkAccessManager manager; 
        QEventLoop loop; 
        qDebug() << "Reading code form " << URLSTR; 
    //发出请求 
        QNetworkReply *reply = manager.get(QNetworkRequest(url)); 
    //请求结束并下载完成后,退出子事件循环 
        QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); 
    //开启子事件循环 
        loop.exec(); 


    //将读到的信息写入文件 
        code = reply->readAll(); 
        QFile file(FILE_NAME); 
        file.open(QIODevice::WriteOnly); 
        QTextStream out(&file); 
        out << code << endl; 
        file.close(); 
       qDebug() << "Finished, the code have written to " << FILE_NAME;
}

需要引用

#include <QUrl>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
#include <QFile>
#include <QDebug>
好这下你可以在文件夹中得到code.txt文件了

3. 利用正则表达式提取所需要的内容或URL


该部分为读取txt中所下载的源代码,显示在旁边的textEdit中,利用正则表达式筛选出所需内容,append到下方的listWidget中,同时显示数量
代码写在一个按钮槽函数中
 

void Widget::on_btnGet_clicked()
{
     //初始化
        strl.clear();
        ui->listWidget->clear();

     //Qt读取txt文件
        QString displayString;
        QFile file("C:/Users/90546/Desktop/Qt/build-qtPaChong-Desktop_Qt_5_14_2_MinGW_64_bit-Debug/debug/code.txt");

        if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
        {
            qDebug()<<"Can't open the file!"<<endl;
        }

        QTextStream in(&file);
     //采用GB2312编码
        in.setCodec("GB2312");
        while(!in.atEnd())
         {
             QString line=in.readLine()+'\n';
             displayString.append(line);
         }
         ui->textEdit->clear();

     //显示在textEdit中
         ui->textEdit->setPlainText(displayString);

     //正则表达式
        QString sstr=ui->lineEditZhengZe->text();

        QRegExp reg(sstr);

        int u=0;
        for(int pos=0;pos=reg.indexIn(displayString,pos),pos>=0; pos+=reg.matchedLength())
        {
           strl.append(reg.cap(0));
           qDebug()<<pos; //返回查找到序号
           qDebug()<<strl[u++];//返回匹配到的字串
        }

     //删除重复项
        for (int i = 0; i < strl.size(); i++)
            {
                for (int k = i + 1; k <  strl.size(); k++)
                {
                    if ( strl[i] ==  strl[k])
                    {
                        strl.removeAt(k);
                        k--;
                    }
                }
            }

     //添加listWidget
        for(int i=0; i<strl.size();i++){
            ui->listWidget->addItem(strl[i]);
        }
        if(strl.size()==0){
            strl.append( "no date");
        }

     //将URL拼接后显示在下载的框中,显示数量
        ui->lineEditUrlDownLoad->setText("https:"+strl[0]);
        ui->labelNum->setNum(strl.size());


}

好,现在你有了想要下载的图片的URL

 

4.利用URL下载图片


这一部分我把功能分为了两块,一块为单次下载,通过点击下一连接切换目标URL,点击下载下载显示在文字框中的URL

下一连接按钮内容,用于切换下载lineEdit中的URL

void Widget::on_btnDownLoadFile_2_clicked()
{
        static int i=0;
        if(i< ui->labelNum->text().toInt()){
            ui->lineEditUrlDownLoad->setText("https:"+strl[i++]);
        }else{
            QMessageBox::information(this, "last", "全部下载完毕!");
        }
        ui->labelNumLast->setNum(i);
}

点击下载内容,这一按钮比较传统,就是http下载,我也是在网上找的,包含一个InitGetRequest函数
 

void Widget::on_btnDownLoadFile_clicked()
{
    //提取最后一个斜杠后内容作为下载的文件名
          QString url=ui->lineEditUrlDownLoad->text();
        int nindex= url.lastIndexOf('/'); //查找最后一个/
        QString str=url.mid(nindex); //从最后一个/一直到字符串结尾

    //保存的目标文件夹
        QString strFilePath = "C:/Users/90546/Desktop/Qt/zZSearch Engine" +str ;

        qDebug() << url ;

    //建立file并写文件
        QFile file;
        file.setFileName(strFilePath);
        if(file.open(QIODevice::WriteOnly))
        {
            QByteArray byte = Widget::InitGetRequest(url, "downImgFromUrl");
            file.write(byte);
            file.close();
        }

}

//get
QByteArray Widget::InitGetRequest(QString url, QString obj)
{
    //循环拼接
        QString baseUrl =url;
    //构造请求
        QNetworkRequest request;
        request.setUrl(QUrl(baseUrl));
        QNetworkAccessManager *manager = new QNetworkAccessManager();
    // 发送请求
        QNetworkReply *pReplay = manager->get(request);
    //开启一个局部的事件循环,等待响应结束,退出
        QEventLoop eventLoop;
        QObject::connect(pReplay,SIGNAL(finished()), &eventLoop, SLOT(quit()));

    //add timeout deal
        QTimer *tmpTimer = new QTimer();
        connect(tmpTimer,SIGNAL(timeout()),&eventLoop, SLOT(quit()));
        tmpTimer->setSingleShot(true);
        tmpTimer->start(5000);
        eventLoop.exec();
        tmpTimer->stop();

        if (pReplay->error() == QNetworkReply::NoError)
        {
          qInfo() << QString("request %1 NoError").arg(obj);
        }
        else
        {
            qWarning()<<QString("request %1 handle errors here").arg(obj);
            QVariant statusCodeV = pReplay->attribute(QNetworkRequest::HttpStatusCodeAttribute);
      //statusCodeV是HTTP服务器的相应码,reply->error()是Qt定义的错误码,可以参考QT的文档
          qWarning()<<QString("request %1 found error ....code: %2 %3").arg(obj).arg(statusCodeV.toInt()).arg((int)pReplay->error());
          qWarning(qPrintable(pReplay->errorString()));
        }
    //获取响应信息
        QByteArray bytes = pReplay->readAll();
        return bytes;
}

注意.h文件的声明

 public:

 QString code; //网页源代码
 QByteArray InitGetRequest(QString url, QString obj);
 QStringList strl;

至于自动下载我目前没啥用就不写了,你可以用Qtimer定时器依次调用下载的函数,就作为家庭作业交给你自己写了
恭喜我们一起写了个爬图片的爬虫,如果你想要其他的内容,学学正则表达式,改一下表达式那一栏的内容就行。

Qt的执行代码在(https://download.csdn.net/download/weixin_44640149/16010220),欢迎下载,我是曦泽周。

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL可以通过链接分析、站点地图、搜索引擎等方式获取。 请求网页: 爬虫使用HTTP或其他协议向目标URL发起请求,获取网页的HTML内容。这通常通过HTTP请求库实现,如Python中的Requests库。 解析内容: 爬虫对获取的HTML进行解析,提取有用的信息。常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标数据,如文本、图片、链接等。 数据存储: 爬虫将提取的数据存储到数据库、文件或其他存储介质中,以备后续分析或展示。常用的存储形式包括关系型数据库、NoSQL数据库、JSON文件等。 遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施,如验证码、IP封锁等。爬虫工程师需要设计相应的策略来应对这些挑战。 爬虫在各个领域都有广泛的应用,包括搜索引擎索引、数据挖掘、价格监测、新闻聚合等。然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值