2017-03-09 3 views
2

Ich habe ein Problem mit dem Web-Scrapping in NodeJS, ich möchte einige Daten von der Remote-Webseite nehmen, aber die Daten werden in HTML aus dem Javascript eingefügt. Ich fing an, PhantomJS zu benutzen, und es funktioniert großartig außer einer Sache, die mich daran hindert, meinen Job zu beenden. PhantomJS arbeitet zu langsam, dieser Codeschnipsel benötigt ungefähr 14 Sekunden zum Ausführen !?PhantomJS open() zu langsam

var page = require('webpage').create(); 
page.open('https://www.halooglasi.com/nekretnine/izdavanje-stanova/novi-beograd---novi-merkator-id19270/5425485514649', function() { 
    phantom.exit(); 
    }); 

mit Anfrage-Bibliothek, die nur Rohdaten seine viel schneller zurück, ein wenig mehr als eine Sekunde PhantomJS arbeitet weitere 13 Sekunden oder so. Es sieht so aus, als ob PhantomJS viele unnötige Operationen macht, die ich nicht brauche, ich muss keine Bilder Videos oder irgendetwas rendern, ich brauche nur Javascript um es auszuführen, also kann ich cheerio verwenden, um die Daten von html zu bekommen. Können Sie mir sagen, wie ich PhantomJS beschleunigen oder ein anderes schnelleres Webkit für meine Bedürfnisse verwenden kann?

Antwort

6

Sie können verschiedene Maßnahmen ergreifen, um die Verarbeitungszeit zu verkürzen.

1. Holen Sie sich einen leistungsfähigeren Server/Computer (wie Mathieu richtig bemerkt).

Ja, Sie könnten argumentieren, dass dies für die Frage irrelevant ist, aber in Sachen des Kratzen ist es sehr viel. Bei einem Budget von 8 VPS ohne Optimierung lief das ursprüngliche Skript für 9589ms, was bereits eine Verbesserung von ~ 30% darstellt.

2. Schalten Sie die Bilder aus. Es wird helfen ... ein bisschen. 8160ms Ladezeit.

page.settings.loadImages = false; 

3. Analysieren Sie die Seite, suchen und löschen Sie unnötige Netzwerkanforderungen.

Auch in einem normalen Browser wie Google Chrome lädt die Website langsam: 129 Anfragen/8.79s Ladezeit mit AdblockPlus. There are a lot of requests (gif, 1Mb), viele, wenn sie für Websites von Drittanbietern wie Facebook, Twitter (um Widgets zu holen) und auf Anzeigenseiten sind.

Wir können sie stornieren:

block_urls = ['gstatic.com', 'adocean.pl', 'gemius.pl', 'twitter.com', 'facebook.net', 'facebook.com', 'planplus.rs']; 

page.onResourceRequested = function(requestData, request){ 
    for(url in block_urls) { 
     if(requestData.url.indexOf(block_urls[url]) !== -1) { 
      request.abort(); 
      console.log(requestData.url + " aborted"); 
      return; 
     } 
    } 
} 

Die Ladezeit für mich jetzt nur 4393ms, während die Seite geladen wird und verwendbar: PhantomJS screenshot

Ich denke nicht viel mehr getan werden kann, ohne basteln mit dem Code der Seite, weil sie nach der Seitenquelle ziemlich skriptlastig ist.

Der gesamte Code:

var page = require('webpage').create(); 
var fs = require("fs"); 

// console.time polyfill from https://github.com/callmehiphop/console-time 
;(function(console) { 
    var timers; 
    if (!console) { 
    return; 
    } 
    timers = {}; 
    console.time = function(name) { 
    if (name) { 
     timers[ name ] = Date.now(); 
    } 
    }; 
    console.timeEnd = function(name) { 
    if (timers[ name ]) { 
     console.log(name + ': ' + (Date.now() - timers[ name ]) + 'ms'); 
     delete timers[ name ]; 
    } 
    }; 
}(window.console)); 

console.time("open"); 

page.settings.loadImages = false; 
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36'; 
page.viewportSize = { 
    width: 1280, 
    height: 800 
}; 

block_urls = ['gstatic.com', 'adocean.pl', 'gemius.pl', 'twitter.com', 'facebook.net', 'facebook.com', 'planplus.rs']; 
page.onResourceRequested = function(requestData, request){ 
    for(url in block_urls) { 
     if(requestData.url.indexOf(block_urls[url]) !== -1) { 
      request.abort(); 
      console.log(requestData.url + " aborted"); 
      return; 
     } 
    }    
} 

page.open('https://www.halooglasi.com/nekretnine/izdavanje-stanova/novi-beograd---novi-merkator-id19270/5425485514649', function() { 
    fs.write("longload.html", page.content, 'w'); 

    console.timeEnd("open"); 

    setTimeout(function(){ 
     page.render('longload.png'); 
     phantom.exit(); 
    }, 3000); 

}); 
+2

ich in den Ergebnissen interessiert bin, kommentieren Sie bitte auf, wie ist das für Sie ausgearbeitet. – Vaviloff

+3

Vielen Dank, das hat mir sehr geholfen. Die Ratschläge, die Sie mir gegeben haben, beschleunigen den Prozess sehr! Es gibt noch eine Sache, die für jemanden mit dem gleichen Problem nützlich sein könnte, es gibt eine weitere Methode, die nützlich ist und das ist "page.settings.resourceTimeout", wenn Sie dies auf 1000 Millisekunden setzen, dann macht phantomJS nur seine Aufgabe eine Sekunde und dann beendet, kann dies nützlich sein, obwohl manchmal Ihre Inhalte nicht geladen werden, wenn die Zeit zu niedrig eingestellt ist, so ist es nicht eine sehr sichere Lösung.Vielen Dank für Ihre Mühe! –