2010-10-11 9 views
3

Je veux écrire un programme en utilisant Qt qui télécharge beaucoup de pages Web HTML, environ 5000, à partir d'un site chaque jour. Après avoir téléchargé ces pages, j'ai besoin d'extraire des données en utilisant DOM Query, en utilisant le module WebKit, puis de stocker ces données dans une base de données.Téléchargement en vrac de pages Web en utilisant Qt

Quelle est la meilleure façon/correcte/efficace de faire cela, en particulier la phase de téléchargement et d'analyse? Comment gérer ce nombre de requêtes et comment créer le "gestionnaire de téléchargement"?

+1

Envisagez d'utiliser un binaire externe comme 'wget' pour le téléchargement –

Répondre

2

Pour télécharger les pages, il est logique d'utiliser une bibliothèque dédiée comme libcurl

0

cela a déjà été répondu, mais est ici une solution en utilisant ce que vous avez demandé, et qui faisait cela avec QT.

Vous pouvez créer un (site Web Crawler) en utilisant QT (en particulier QNetworkManager, QNetworkRequests, QNetworkReply). Je ne suis pas sûr exactement si c'est la bonne façon de gérer une telle tâche, mais j'ai trouvé en utilisant plusieurs threads, vous pouvez maximiser l'efficacité et gagner du temps. (S'il vous plaît quelqu'un me dire s'il y a une autre façon/ou confirmer si cela est une bonne pratique)

Concept est qu'une liste de travail est mis en attente, et un travailleur effectuera le travail, et après avoir reçu les informations/html, traitez-le, puis passez à l'élément suivant.

Travailleur de la classe Object classe devrait accepte une URL, les processus et télécharge un données HTML de l'URL et traite ensuite les informations lors de la réception.

Créer une file d'attente et le gestionnaire de la file d'attente J'ai créé un QQueue < QString> urlList pour contrôler la quantité d'éléments simultanés en cours de traitement et la liste des tâches à accomplir.

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(); 


} 

Une fois que vous obtenez vos informations, je viens de traiter les informations d'un QString, mais je suis sûr que vous pouvez travailler sur la façon d'utiliser un analyseur DOM une fois que vous arrivez à ce stade. J'espère que ceci est un exemple suffisant pour vous aider.

Questions connexes