关于 QNetworkAccessManager 如果访问网页非常频繁
QByteArray WebDownload::download(const QString &url){
QNetworkAccessManager manager;
QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(url)));
QObject::connect(reply, &QNetworkReply::finished, this,[=](){
QNetworkReply *reply = (QNetworkReply *)sender();
emit downloadOk(reply->readAll());
reply->deleteLater();
});
}
例如,你用循环去调用
你会发现所有结果都是莫名其妙一样的!一样的!一样的!重要的事说三次
WebDownload *web = new WebDownload(this);
for(int i=1;i<10;i++){
web->download(QString("http://www.1kkk.com/manhua-shaonianrexue-p%1/").arg(i));
connect(web,&WebDownload::downloadOk,this,[=,i](const QString &data){
FileOperation::writeText(
QString("E://%1.html").arg(i)
,data
,QTextCodec::codecForName("utf-8"));
});
}
#include <QStringList>
#include <QObject>
#include <QNetworkAccessManager>
class QTextCodec;
class QByteArray;
class QNetworkReply;
class WebDownload:public QObject
{
Q_OBJECT
public:
WebDownload(QObject*parent=nullptr);
QByteArray download(const QString &url);
static QTextCodec *getCode(const QByteArray &data);
static QStringList replaceHtml(const QString &pattern, const QString &data);
static QList<QStringList> replaceHtml(const QString &pattern, int number, const QString &data);
signals:
void downloadOk(const QByteArray &data);
private slots:
void finished();
private:
QNetworkAccessManager *m_Manager;
};
#endif // WEBDOWNLOAD_H
#include "webdownload.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTextCodec>
#include <QEventLoop>
#include <QUrl>
#include <QDebug>
WebDownload::WebDownload(QObject *parent):QObject(parent)
{
m_Manager = new QNetworkAccessManager(this);
}
QByteArray WebDownload::download(const QString &url)
{
QEventLoop loop;
QNetworkReply *reply = m_Manager->get(QNetworkRequest(QUrl(url)));
QObject::connect(reply, &QNetworkReply::finished, &loop,&QEventLoop::quit);
loop.exec();
if(reply->error() == QNetworkReply::NoError){
int state = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if(state == 301){
QString url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
download(url);
}
}
const QByteArray &tmp = reply->readAll();
manager.deleteLater();
reply->deleteLater();
return tmp;
}
void WebDownload::finished()
{
QNetworkReply* reply = (QNetworkReply*)sender();
if(reply->error() == QNetworkReply::NoError){
int state = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if(state == 301){
QString url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toString();
download(url);
}
}
emit downloadOk(reply->readAll());
reply->deleteLater();
}
QTextCodec *WebDownload::getCode(const QByteArray &data)
{
QRegExp re("charset=([-a-zA-Z0-9]+)");
re.indexIn(data);
return QTextCodec::codecForName(re.cap(1).toLatin1());
}
QStringList WebDownload::replaceHtml(const QString &pattern, const QString &data)
{
int pos = 0;
QStringList tmp;
QRegExp regexp(pattern);
regexp.setMinimal(true);
while((pos = regexp.indexIn(data,pos)) != -1){
tmp << regexp.cap(1);
pos += regexp.matchedLength();
}
return tmp;
}
QList<QStringList> WebDownload::replaceHtml(const QString &pattern, int number, const QString &data)
{
int pos = 0;
QList<QStringList> tmp;
QRegExp regexp(pattern);
regexp.setMinimal(true);
int i,j=0;
while((pos = regexp.indexIn(data,pos)) != -1){
tmp << QStringList();
for(i=1; i<=number; i++)
tmp[j] << regexp.cap(i);
j++;
pos += regexp.matchedLength();
}
return tmp;
}
这样调用....
WebDownload *web = new WebDownload(this);
for(int i=1;i<10;i++){
QtConcurrent::run([=,web](){
auto data = web->download(QString("http://www.1kkk.com/manhua-shaonianrexue-p%1/").arg(i));
FileOperation::writeText(
QString("E://%1.html").arg(i)
,data
,QTextCodec::codecForName("utf-8"));
});
}