Qt之http通讯简单用法 /编写必应主页小爬虫,获取当日壁纸

来源:互联网 发布:搜狗拼音输入法云计算 编辑:程序博客网 时间:2024/06/05 07:59

摘要:本人希望能够每天更换桌面背景,又觉得常规手动步骤太过麻烦(从网上找图片->下载至本地->打开本地路径->右键设为壁纸),鉴于必应壁纸质量很高,索性写了一个程序自动实现其全部过程。(文末附本程序完整源代码的链接)
本文介绍了从网上爬取图片的实现,即Qt的http网络通讯的简单应用。后半部分调用本地系统API设置壁纸的过程,在其他文章另有介绍。

本人亲测平台包含: Win10,Ubuntu16.04LTS
运行环境:Qt5.7.0

第一次Get

通过QNetworkAccessManager类的get函数,爬下Bing主页全部源码至本地的一个txt文件中,便于后续的分析处理。小贴士:用QNetworkRequest类的setUrl函数设定url。

QNetworkAccessManager manager;//要用到connect,所以在头文件中提前声明此对象
void WallPaper::getWholeWebSource(){    showStatusTips(PICTURE_DOWNLOADING);//一个用于显示当前状态的函数,详见文末链接程序github源码    QUrl url("http://cn.bing.com/");    QNetworkRequest request;    request.setUrl(url);//将完成信号与我自定义的槽函数findPicUrl相连,用finished信号传递reply信息至槽函数中    connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(findPicUrl(QNetworkReply*)));//在连接了信号与槽之后,就可以进行get操作。get一旦完成,会自动触发finished信号,从而转至槽函数    manager.get(request);}

bing主页的源码分析

一旦对应第一步当中的get的finished信号被触发,则转至该槽函数findPicUrl,同时传递过来一个对象QNetworkReply *reply。通过reply->readAll()读取get到的内容。

分析源码,会发现壁纸URL并不完整,只是一个片段,尚无法通过它获取壁纸图片,需要自己再稍微拼接一下。因此,具体步骤为:1.通过一定的算法找到此片段;2.截取之;3.与http://cn.bing.com/拼接;

void WallPaper::findPicUrl(QNetworkReply *reply){    disconnect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(findPicUrl(QNetworkReply*)));    if(reply->error() == QNetworkReply::NoError)    {        QByteArray webContent = reply->readAll();        QFile file("测试文件.txt");//写成一个可阅读的txt文档,用于程序测试        file.open(QIODevice::ReadWrite);        file.write(webContent);        file.close();        QByteArray targetUrl = "/az/hprichbg/rb/";//目标url片段,通过它抓取到完整的壁纸网址        int indexStart = -1;        int indexEnd = -1;        indexStart = webContent.indexOf(targetUrl);        if(indexStart != -1)//若在获取到的网页源码中找到了所需url,则get之        {            qDebug("找到了壁纸的url:");            webContent = webContent.mid(indexStart);//截取右侧            indexEnd = webContent.indexOf("jpg");            indexEnd = indexEnd + 2;            QUrl url("http://cn.bing.com" + webContent.left(indexEnd + 1));//继续截取并拼接            qDebug()<<url;            emit urlFound(url);//发射了一个信号        }        else            showStatusTips(URL_NOT_FOUND);//一个用于显示当前状态的函数,详见文末链接程序github源码    }    else        showStatusTips(NETWORK_CONNECTION_FAILED, reply->errorString());}

上文中你发现,由于findPicUrl函数也发射了一个信号,urlFound(url),因此在构造函数处加一个connect

//当最终计算出壁纸的目标url后,则转至downloadPic函数,正式开始下载壁纸connect(this, SIGNAL(urlFound(QUrl)), this, SLOT(downloadPic(QUrl)));

第二次Get

当urlFound信号发射后,转至downloadPic函数,get的用法与前文一致

void WallPaper::downloadPic(QUrl url){    QNetworkRequest request;    request.setUrl(url);    connect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(savePic(QNetworkReply*)));    manager.get(request);//用finished信号传递reply}

IO操作,保存至本地

当返回信号finished时,将bing返回的reply信息,即图片,保存至本地

void WallPaper::savePic(QNetworkReply *reply){    disconnect(&manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(savePic(QNetworkReply*)));    if(reply->error() == QNetworkReply::NoError)    {        QPixmap picture;//读取IO信息        QByteArray picData = reply->readAll();        if(!picture.loadFromData(picData, "JPG"))//用QPixmap定义的对象picture,读取从bing网站传过来的数据,格式为jpg的图片        {            showStatusTips(LOAD_FROM_DATA_FAILED, QString("%1").arg(picData.size()));            return;        }//定义保存路径filepath        filePath = QDir::homePath() + "/" + "Pictures/";        QDir dir;        dir.mkdir(filePath);        filePath += QDateTime::currentDateTime().toString("yyyy-MM-dd") + "_Bing_txmy.jpg";//save函数保存至本地        if(!picture.save(filePath))        {            qDebug()<<"图片保存失败!";        }        else        {//软件其他操作            showStatusTips(WALLPAPER_READY);            showStatusTips(COUNT_DOWN_TO_CLOSE);            emit picSaved(filePath);            DataCenter &dc = DataCenter::getInstance();            QStringList paths = dc.getPicFilePaths();            int index = paths.indexOf(filePath);            if(index != -1)                dc.setCurrentIndex(index);        }    }    else        showStatusTips(DOWNLOAD_FAILED, reply->errorString());}

——————

Github源代码
一款简约的壁纸设置程序 https://github.com/polarbear0330/DeskWallPaper

本人联系方式:362036379@sjtu.edu.cn,tfy.hi@163.com

原创粉丝点击