【问题标题】:Bulk download of web pages using Qt使用 Qt 批量下载网页
【发布时间】:2010-10-11 21:29:59
【问题描述】:

我想使用 Qt 编写一个程序,每天从一个站点下载大量 HTML 网页,大约 5000 个。下载这些页面后,我需要使用 DOM Query 提取一些数据,使用 WebKit 模块,然后将这些数据存储在数据库中。

哪种方法最好/正确/有效,尤其是下载和分析阶段?如何处理这么多的请求以及如何创建“下载管理器”?

【问题讨论】:

  • 考虑使用像wget这样的外部二进制文件进行下载

标签: c++ html qt download


【解决方案1】:

要下载页面,使用像libcurl这样的专用库是有意义的

【讨论】:

    【解决方案2】:

    这已经得到解答,但这里有一个使用您要求的解决方案,并且使用 QT 进行此操作。

    您可以使用 QT(特别是 QNetworkManager、QNetworkRequests、QNetworkReply)制作(网站爬虫)。我不确定这是否是处理此类任务的正确方法,但我发现利用多个线程可以最大限度地提高效率并节省时间。 (请有人告诉我是否有其他方法/或确认这是否是好的做法)

    概念是一个工作列表排队,一个worker来执行工作,收到信息/html后,处理它,然后继续下一项。

    类工作者对象 类应该接受一个 Url,处理和下载一个 url 的 html 数据,然后在收到信息时处理。

    为队列创建队列和管理器 我创建了一个 QQueue 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 解析器。

    我希望这是一个足以帮助你的例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-02
      • 1970-01-01
      • 2023-03-23
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多