我想用Qt编写一个程序,每天从一个站点下载大量5000个HTML网页。下载页面后,我需要使用DOM Query提取一些数据,使用WebKit模块,然后将数据存储在数据库中。
哪种方法最好/正确/有效,特别是下载和分析阶段?如何处理这些请求以及如何创建“下载管理器”?
答案 0 :(得分:2)
要下载页面,使用libcurl
等专用库是有意义的答案 1 :(得分:0)
这已经得到了解答,但这里有一个使用你要求的解决方案,而且这是用QT做的。
您可以使用QT(特别是QNetworkManager,QNetworkRequests,QNetworkReply)制作(网站抓取工具)。我不确定这是否是处理此类任务的正确方法,但我发现利用多个线程可以最大限度地提高效率并节省时间。 (请有人告诉我,如果有其他方式/或确认这是不是好的做法)
概念是工作列表排队,工作人员将执行工作,并在收到信息/ html后处理它,然后继续下一个项目。
类工作者对象 类应接受Url,处理并下载url的html数据,然后在收到时处理这些信息。
为队列创建队列和管理器 我创建了一个QQueue<的QString> urlList用于控制正在处理的并发项的数量以及要完成的任务列表。
QQueue <String> workQueue; //First create somewhere a
int maxWorkers = 10;
//Then create the workers
void downloadNewArrivals::createWorkers(QString url){
checkNewArrivalWorker* worker = new checkNewArrivalWorker(url);
workQueue.enqueue(worker);
}
//Make a function to control the amount of workers,
//and process the workers after they are finished
void downloadNewArrivals::processWorkQueue(){
if (workQueue.isEmpty() && currentWorkers== 0){
qDebug() << "Work Queue Empty" << endl;
} else if (!workQueue.isEmpty()){
//Create the maxWorkers and start them in seperate threads
for (int i = 0; i < currentWorkers && !workQueue.isEmpty(); i++){
QThread* thread = new QThread;
checkNewArrivalWorker* worker = workQueue.dequeue();
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), this, SLOT(reduceThreadCounterAndProcessNext()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
currentWorkers++;
}
}
}
//When finished, process the next worker
void downloadNewArrivals::reduceThreadCounterAndProcessNext(){
currentWorkers--; //This variable is to control amount of max workers
processWorkQueue();
}
//Now the worker
//The worker class important parts..
void checkNewArrivalWorker::getPages(QString url){
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QNetworkRequest getPageRequest = QNetworkRequest(url); //created on heap
getPageRequest.setRawHeader( "User-Agent", "Mozilla/5.0 (X11; U; Linux i686 (x86_64); "
"en-US; rv:1.9.0.1) Gecko/2008070206 Firefox/3.0.1" );
getPageRequest.setRawHeader( "charset", "utf-8" );
getPageRequest.setRawHeader( "Connection", "keep-alive" );
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyGetPagesFinished(QNetworkReply*)));
connect(manager, SIGNAL(finished(QNetworkReply*)), manager, SLOT(deleteLater()));
manager->get(getPageRequest);
}
void checkNewArrivalWorker::replyGetPagesFinished(QNetworkReply *reply){
QString data = reply->readAll(); //Here data will hold your html to process as needed...
reply->deleteLater();
emit finished();
}
获取信息之后,我刚刚从QString处理了信息,但是一旦到达这个阶段,我确定你可以知道如何使用DOM解析器。
我希望这足以帮助你。