захаваць HTML вываду старонкі пасля выканання JavaScript на старонках

Існуе сайт, я спрабую драпаць, што першыя загружае HTML/JS змяняе форму палёў уводу з дапамогай JS, а затым паведамленні. Як я магу атрымаць канчатковы HTML выснову пасланай старонкі?

Я спрабаваў зрабіць гэта з 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 і г.д.)

дзякуй

47
Ці ёсць у вас выкарыстоўваць Python? Ці з'яўляецца Java варыянт?
дададзена аўтар OakNinja, крыніца
Вы таксама можаце атрымаць змесціва старонкі, выкарыстоўваючы document.outerHTML
дададзена аўтар MIdhun Krishna, крыніца

7 адказы

выхадны код у вас ёсць правільны, але ёсць праблемы з сінхроннасцю. Выхадныя лініі, якія вы павінны ў цяперашні час выконваюцца перад старонка загрузіцца. Вы можаце звязаць у onLoadFinished зваротнага выклік, каб даведацца, калі гэта адбудзецца. Глядзіце поўны код ніжэй.

    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 инлайн, як у вас ёсць. Хранаметраж складаная рэч у phantomjs, часам я адчуваю з SetTimeout, каб убачыць, калі часу з'яўляецца праблемай.

25
дададзена
Чаму вам трэба вызначыць onLoadFinished двойчы?
дададзена аўтар Max, крыніца
наконт вобразаў і стыляў?
дададзена аўтар Toolkit, крыніца

This can easily be done with some PHP code and javascript use fopen() and fwrite() and this function to save it: var generatedSource = new XMLSerializer().serializeToString(document);

8
дададзена

Калі я скапіяваў свой код непасрэдна, і змяніў URL для www.google.com, ён працаваў выдатна, з двума файлаў захоўваюцца:

  • 1.html
  • export.png

Майце на ўвазе, што файлы будуць запісаныя ў тэчку, вы запусціце скрыпт з не там, дзе знаходзіцца файл .js

4
дададзена

Пасля 2-х доўгіх дзён з усіх сіл і расчараванні, я, нарэшце, атрымаў свой аналагічны пытанне вырашана. Што ж трук быў waitfor.js прыклад < A HREF = "http://phantomjs.org/examples/" отн = "NOFOLLOW noreferrer"> 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'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();
        });
    }
});
2
дададзена

адзін падыход, які прыходзіць на розум, акрамя выкарыстання абезгалоўленага браўзэра, пэўна, дзеля імітацыі Аякса выклікаў і ансамбль старонкі паста-працэс, запыту па запыце .. гэта, аднак, часта роду складана і павінна выкарыстоўвацца ў якасці апошняга сродку, калі вы сапраўды не падабаецца капацца яваскрипта код ..

1
дададзена

Я паспрабаваў некалькі падыходаў да падобнай задачы і дасягнення найлепшых вынікаў, якія я атрымаў з дапамогай Selenium.

Перш чым я паспрабаваў PhantomJS і Cheerio . Фантом быў збой занадта часта пры выкананні JS на гэтай старонцы.

0
дададзена

Я выкарыстоўваю 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();
        });
    }
});

См дакументы для і getHTML .

0
дададзена