html-uitvoer van de pagina opslaan na uitvoering van het javascript van de pagina

Er is een site die ik probeer te schrapen, die eerst een html/js laadt
wijzigt de formulierinvoervelden met js en vervolgens POST’s.
Hoe kan ik de uiteindelijke html-uitvoer van de POST-pagina krijgen?

Ik heb geprobeerd dit te doen met phantomjs, maar het lijkt alleen een optie te hebben om afbeeldingsbestanden weer te geven. Googlen suggereert dat het mogelijk moet zijn, maar ik weet niet hoe. Mijn poging:

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();
});

Deze code wordt gebruikt voor een klant, ik kan niet verwachten dat hij te veel pakketten installeert (nodejs , casperjs enz.)

Bedankt


Antwoord 1, autoriteit 100%

de uitvoercode die u heeft is correct, maar er is een probleem met de synchroniciteit. De uitvoerregels die u hebt, worden uitgevoerd voordat de pagina klaar is met laden.
U kunt aansluiten bij de onLoadFinished Callback om erachter te komen wanneer dat gebeurt. Zie de volledige code hieronder.

   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() {
      });
    });

Als je een site als Google gebruikt, kan het misleidend zijn omdat het zo sneller laadt, dat je vaak een screengrab inline kunt uitvoeren zoals je het hebt. Timing is een lastig iets in phantomjs, soms test ik met setTimeout om te zien of timing een probleem is.


Antwoord 2, autoriteit 15%

Toen ik je code rechtstreeks kopieerde en de URL wijzigde in www.google.com, werkte het prima, met twee opgeslagen bestanden:

  • 1.html
  • export.png

Houd er rekening mee dat de bestanden worden geschreven naar de locatie waar u het script uitvoert, niet waar uw .js-bestand zich bevindt


Antwoord 3, autoriteit 7%

Na 2 lange dagen van worstelen en frustratie heb ik eindelijk mijn soortgelijk probleem opgelost. De truc was het waitfor.jsvoorbeeld in officiële website van PhantomJS. Wees blij!

"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();
        });
    }
});

Antwoord 4

Ik heb verschillende benaderingen geprobeerd aan dezelfde taak en de beste resultaten die ik heb gebruikt Selenium.

Voordat ik Phantomjs en Cheerio probeerde. Phantom crashte te vaak tijdens het uitvoeren van JS op de pagina.


Antwoord 5

Ik gebruik CAPERJS om tests met Phantomjs uit te voeren. Ik heb deze code toegevoegd aan mijn traandown functie:

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();
        });
    }
});

Zie documenten voor capture en Gethtml .


Antwoord 6

Eén benadering die bij mij opkomt, naast het gebruik van een hoofdleme browser is natuurlijk om de AJAX-oproepen te simuleren en om het pagina-postproces te ensemble te vormen, op verzoek. Dit is echter vaak een beetje lastig en moet worden gebruikt als een Laatste resort, tenzij je echt graag door JavaScript-code wilt graven.


Antwoord 7

Dit kan eenvoudig worden gedaan met een PHP-code en JavaScript
gebruik fopen () en fwrite ()
en deze functie om het op te slaan:
var gegenereerde resource = nieuwe XMLSISTERIER (). SerializetoString (document);

Other episodes