2016-07-20 15 views
0

zuerst, lassen Sie mich darauf hinweisen, dass ich neu zu node.js und asynchrone Programmierung bin, so dass mein Code möglicherweise wirklich schlecht ist. Ich versuche einen Webscrapper mit webdriverio und cheerio zu erstellen. In diesem Webscrapper muss ich eine Abfrage erstellen, die Ergebnisse der Abfrage verwerfen, während ich zwischen Inhaltsseiten und Ergebnisseiten umschalte, und dann eine neue Abfrage durchführen, nachdem die Ergebnisse erschöpft sind. Dies ist der Code, den ich mit so weit gekommen sind (unter der Annahme, dass der Client bereits eingeleitet und die Funktion „make_new_query()“ von einem „.then()“ Aktion wird genannt):Verkettung verspricht mit Webdriverio

function scrapt_content(){ 
// if array of content links is exhausted -> move to next page or perform new query 
if(contents_pointer == contents.length){ 

    return client.isExisting("li.next-page > a").then(function(isExisting){ 
     // if there is a link to a a new page of results -> move to new page 
     if(isExisting){ 
      return change_pages(); 
     } else { 
      return make_new_query(); 
     }; 
    }); 

// change to new and scrapt it 
} else { 

    // var parsed = cheerio.load(res); 
    ... scrap content using cherio ... 
    . 
    . 
    . 
    contents_pointer++; 

    return scrapt_content(); 

    }) 
}; 
}; 

function change_pages(){ 

client 
    .click("li.next-page > a") 
    .getAttribute("h2 a", "href"); 
    .then(function(res){ 
     contents_pointer = 0; 
     news_links = res; 
     return scrapt_content(); 
    }) 
} 

function make_new_query(){ 
. 
. 
. 
client.url(new_query_url) 
    .getAttribute("h2 > a", "href") 
    .then(function(res){ 
     content_links = res; 
     return scrapt_content(); 
    }) 
} 
} 

Die Problem ist, dass nach dem Aufrufen der ersten Seite des Inhalts zu verschrotten (der Code führt die Abfrage und diese Seite, die die erste Verknüpfung im Array von content_links), der Webdriver schließt. Es ist so, als ob der Code zuerst die Funktion change_pages ausführt, die scrypt_content aufruft und dann vorzeitig beendet wird. Also nehme ich an, dass der Fehler beim Verketten von Aktionen in dieser Funktion liegt. Kann jemand auf meine Fehler hinweisen, während ich versuche, diese Aktionen zu verketten?

Antwort

0

Sie müssen etwas Code fehlen, weil ich nicht sagen kann, an welchem ​​Punkt Sie den Webdriver schließen. Sie müssen jedoch eine Zusage verwenden, um sicherzustellen, dass die Funktion nicht zurückgegeben wird, bevor die asynchronen Vorgänge abgeschlossen sind. Da Sie sich im Knoten befinden, haben Sie die meisten ES6-Funktionen eingebaut, so dass Sie in der obersten Zeile Ihres Codes "use strict" hinzufügen können (um ES6-Funktionen zu aktivieren) und dann einfach (z. B. mit Ihrer scrypt_content-Funktion):

//this function returns a promise 
 
function scrapt_content(){ 
 
    return new Promise(function(resolve, reject){ 
 
    InsertyourAsyncFunctionHere().then(function(){ 
 
     resolve(); 
 
    }); 
 
    }); 
 
}; 
 

 
//setting promise resolve/reject callbacks with then and catch 
 
scrapt_content.then(function(){ 
 
    //resolve (success) callback content here 
 
}).catch(function(err){ 
 
    //reject (error) callback contenthere 
 
    console.log(err.message) 
 
});