Es gibt eine Website, die ich zu kratzen versuche, die zuerst ein HTML/js lädt Ändert die Formulareingabefelder mit js und dann POSTs . Wie kann ich die endgültige HTML-Ausgabe der geposteten Seite erhalten?
Ich habe versucht, dies mit Phantomjs zu tun, aber es scheint nur eine Option zum Rendern von Bilddateien zu haben. Googeln bedeutet, dass es möglich sein sollte, aber ich kann nicht herausfinden, wie. Mein Versuch:
var page = require('webpage').create();
var fs = require('fs');
page.open('https://www.somesite.com/page.aspx', function () {
page.evaluate(function(){
});
page.render('export.png');
fs.write('1.html', page.content, 'w');
phantom.exit();
});
Dieser Code wird für einen Client verwendet. Ich kann nicht erwarten, dass er zu viele Pakete installiert (nodejs, casperjs usw.).
Vielen Dank
der ausgegebene Code ist korrekt, aber es gibt ein Problem mit der Synchronität. Die Ausgabezeilen, die Sie haben, werden ausgeführt, bevor die Seite vollständig geladen ist. Sie können in den onLoadFinished Callback einbinden, um herauszufinden, wann dies der Fall ist. Siehe vollständigen Code unten.
var page = new WebPage()
var fs = require('fs');
page.onLoadFinished = function() {
console.log("page load finished");
page.render('export.png');
fs.write('1.html', page.content, 'w');
phantom.exit();
};
page.open("http://www.google.com", function() {
page.evaluate(function() {
});
});
Wenn Sie eine Website wie Google verwenden, kann dies zu Täuschungen führen, da sie so schnell geladen wird, dass Sie ein Screengrab-Inline-Programm oft so ausführen können, wie Sie es haben. In phantomjs ist Timing eine knifflige Angelegenheit. Manchmal teste ich mit setTimeout, ob Timing ein Problem ist.
Wenn ich Ihren Code direkt kopiert und die URL in www.google.com geändert habe, hat er mit zwei gespeicherten Dateien einwandfrei funktioniert:
Beachten Sie, dass die Dateien an den Ort geschrieben werden, von dem aus Sie das Skript ausführen, und nicht an den Ort, an dem sich Ihre .js-Datei befindet
Nach zwei langen Tagen des Kämpfens und der Frustration wurde mein ähnliches Problem endlich gelöst. Der Trick war das waitfor.js Beispiel in PhantomJS 'offizielle Website . Sei glücklich!
"use strict";
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
start = new Date().getTime(),
condition = false,
interval = setInterval(function() {
if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
// If not time-out yet and condition not yet fulfilled
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
} else {
if(!condition) {
// If condition still not fulfilled (timeout but condition is 'false')
console.log("'waitFor()' timeout");
phantom.exit(1);
} else {
// Condition fulfilled (timeout and/or condition is 'true')
console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
clearInterval(interval); //< Stop this interval
}
}
}, 250); //< repeat check every 250ms
};
var page = require('webpage').create();
// Open Twitter on 'sencha' profile and, onPageLoad, do...
page.open("http://Twitter.com/#!/sencha", function (status) {
// Check for page load success
if (status !== "success") {
console.log("Unable to access network");
} else {
// Wait for 'signin-dropdown' to be visible
waitFor(function() {
// Check in the page if a specific element is now visible
return page.evaluate(function() {
return $("#signin-dropdown").is(":visible");
});
}, function() {
console.log("The sign-in dialog should be visible now.");
phantom.exit();
});
}
});
Ich benutze CasperJS , um Tests mit PhantomJS auszuführen. Ich habe diesen Code meiner tearDown - Funktion hinzugefügt:
var require = patchRequire(require);
var fs = require('fs');
casper.test.begin("My Test", {
tearDown: function(){
casper.capture("export.png");
fs.write("1.html", casper.getHTML(undefined, true), 'w');
},
test: function(test){
// test code
casper.run(function(){
test.done();
});
}
});
Ich habe verschiedene Ansätze für ähnliche Aufgaben ausprobiert und die besten Ergebnisse mit Selenium erzielt.
Bevor ich PhantomJS und Cheerio ausprobiert habe. Phantom stürzte zu oft ab, als JS auf der Seite ausgeführt wurde.