Сохранить html-вывод страницы после выполнения страницы javascript
Есть сайт, который я пытаюсь очистить, сначала загружает html/js
изменяет поля ввода формы с помощью js, а затем POST.
Как я могу получить окончательный вывод html на странице POSTed?
Я попытался сделать это с помощью phantomjs, но у него есть только возможность рендеринга файлов изображений. Гуглинг вокруг предполагает, что это должно быть возможно, но я не могу понять, как это сделать. Моя попытка:
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();
});
Этот код будет использоваться для клиента, я не могу ожидать, что он установит слишком много пакетов (nodejs, casperjs и т.д.)
Спасибо
Ответы
Ответ 1
код вывода, который у вас есть, является правильным, но есть проблема с синхронностью. Линии вывода, которые у вас есть, выполняются до того, как страница будет загружена.
Вы можете привязать к onLoadFinished Callback, чтобы узнать, когда это произойдет. См. Полный код ниже.
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() {
});
});
При использовании сайта, такого как google, он может обманывать, потому что он загружается так быстрее, что вы часто можете использовать screengrab inline, как и у вас. Сроки - сложная вещь в phantomjs, иногда я тестирую с помощью setTimeout, чтобы определить, является ли время проблемой.
Ответ 2
Когда я скопировал ваш код напрямую и изменил URL-адрес на www.google.com, он работал нормально, с сохраненными двумя файлами:
Имейте в виду, что файлы будут записаны в папку, в которой вы запускаете script, а не там, где находится ваш .js файл.
Ответ 3
После 2 долгих дней борьбы и разочарования я, наконец, решил свою аналогичную проблему. Что было трюком waitfor.js пример в официальный PhantomJS сайт. Будьте счастливы!
"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 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();
});
}
});
Ответ 4
Я попробовал несколько подходов к подобной задаче и наилучшие результаты, полученные с помощью Selenium.
До того, как я попробовал PhantomJS и Cheerio. Phantom слишком часто сбой при выполнении JS на странице.
Ответ 5
Я использую CasperJS для запуска тестов с помощью PhantomJS. Я добавил этот код в свою tearDown:
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();
});
}
});
См. документы для capture и getHTML.
Ответ 6
один подход, который приходит мне на ум, помимо использования безгласного браузера, очевидно, должен имитировать вызовы ajax и ансамбль постпроцесса страницы, запрос по запросу.. это, однако, часто бывает сложным и должно использоваться как в крайнем случае, если вы действительно не хотите копать код javascript..
Ответ 7
Это легко сделать с помощью некоторых php-кодов и javascript
используйте fopen() и fwrite()
и эта функция сохранит его:
var generatedSource = новый XMLSerializer(). serializeToString (document);