प्रेत "पूर्ण" पृष्ठ लोड की प्रतीक्षा नहीं कर रहे हैं


137

मैं कुछ वेब पेज लोड करने के लिए PhantomJS v1.4.1 का उपयोग कर रहा हूं । मेरे पास उनके सर्वर-साइड तक पहुंच नहीं है, मुझे सिर्फ उन्हें इंगित करने वाले लिंक मिल रहे हैं। मैं फैंटम के अप्रचलित संस्करण का उपयोग कर रहा हूं क्योंकि मुझे उस वेब पृष्ठों पर एडोब फ्लैश का समर्थन करने की आवश्यकता है।

समस्या यह है कि कई वेब-साइटें अपनी मामूली सामग्री को async लोड कर रही हैं और यही कारण है कि फैंटम की onLoadFinished कॉलबैक (HTML में onLoad के लिए एनालॉग) बहुत जल्दी निकाल दिया जब सब कुछ अभी भी लोड नहीं हुआ है। क्या कोई सुझाव दे सकता है कि मैं वेबपेज के पूर्ण लोड के लिए प्रतीक्षा कैसे कर सकता हूं, उदाहरण के लिए, विज्ञापन जैसे सभी गतिशील सामग्री वाला स्क्रीनशॉट?


3
मुझे लगता है कि इसका उत्तर स्वीकार करने का समय है
स्पार्टिकस

जवाबों:


76

एक अन्य तरीका यह है कि नियमित रूप से rasterize.js उदाहरण के अनुसार, रेंडर करने से पहले पेज लोड होने के बाद फैंटमजस से थोड़ा इंतजार करने के लिए कहें , लेकिन जावास्क्रिप्ट अतिरिक्त संसाधनों को पूरा करने की अनुमति देने के लिए एक लंबे समय के साथ:

page.open(address, function (status) {
    if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
    } else {
        window.setTimeout(function () {
            page.render(output);
            phantom.exit();
        }, 1000); // Change timeout as required to allow sufficient time 
    }
});

1
हां, वर्तमान में मैं इस दृष्टिकोण से जुड़ा हुआ हूं।
nilfalse

102
यह एक भयानक समाधान है, क्षमा करें (यह PhantomJS की गलती है!)। यदि आप एक पूर्ण सेकंड प्रतीक्षा करते हैं, लेकिन इसे लोड करने में 20ms लगते हैं, तो यह समय की पूरी बर्बादी है (बैच की नौकरियों के बारे में सोचें), या यदि यह एक सेकंड से अधिक समय लेता है, तो यह अभी भी विफल हो जाएगा। इस तरह की अक्षमता और अविश्वसनीयता पेशेवर काम के लिए असहनीय है।
कोडमेनएक्स

9
यहाँ वास्तविक समस्या यह है कि आप कभी नहीं जानते हैं कि जावास्क्रिप्ट लोडिंग पेज को कब पूरा करेगा और ब्राउज़र इसे भी नहीं जानता है। उस साइट की कल्पना करें जिसमें कुछ लूप है जो सर्वर से अनंत लूप में कुछ लोड कर रहा है। ब्राउज़र के दृष्टिकोण से - जावास्क्रिप्ट निष्पादन कभी समाप्त नहीं होता है तो वह कौन सा क्षण है जो आप चाहते हैं कि प्रेत आपको बताए कि यह समाप्त हो गया है? समयबाह्य समाधान के लिए प्रतीक्षा और सर्वोत्तम के लिए उम्मीद के अलावा सामान्य समस्या में यह समस्या अकल्पनीय है।
मैक्सिम गलुष्का

5
क्या यह अभी भी 2016 का सबसे अच्छा समाधान है? ऐसा लगता है कि हमें इससे बेहतर करने में सक्षम होना चाहिए।
एडम थॉम्पसन

6
यदि आप उस कोड के नियंत्रण में हैं जिसे आप पढ़ने की कोशिश कर रहे हैं, तो आप प्रेत js कॉल को स्पष्ट रूप से वापस बुला सकते हैं: phantomjs.org/api/webpage/handler/on-callback.html
एंडी स्मिथ

52

मैं समय-समय पर document.readyStateस्थिति ( https://developer.mozilla.org/en-US/docs/Web/API/document.readyState ) की जांच करूंगा । हालांकि यह दृष्टिकोण थोड़ा क्लिंकी है, आप सुनिश्चित कर सकते हैं कि onPageReadyफ़ंक्शन के अंदर आप पूरी तरह से लोड किए गए दस्तावेज़ का उपयोग कर रहे हैं।

var page = require("webpage").create(),
    url = "http://example.com/index.html";

function onPageReady() {
    var htmlContent = page.evaluate(function () {
        return document.documentElement.outerHTML;
    });

    console.log(htmlContent);

    phantom.exit();
}

page.open(url, function (status) {
    function checkReadyState() {
        setTimeout(function () {
            var readyState = page.evaluate(function () {
                return document.readyState;
            });

            if ("complete" === readyState) {
                onPageReady();
            } else {
                checkReadyState();
            }
        });
    }

    checkReadyState();
});

अतिरिक्त स्पष्टीकरण:

जब "निष्पादन कुछ यादृच्छिक कारणों से लम्बा हो जाता है" तो "ओवरलैपिंग" और दौड़ की स्थिति से बचाव के setTimeoutबजाय नेस्टेड का उपयोग करना । 4ms ( https://stackoverflow.com/a/3580085/1011156 ) की डिफ़ॉल्ट देरी है, इसलिए सक्रिय मतदान कार्यक्रम के प्रदर्शन को बहुत प्रभावित नहीं करेगा।setIntervalcheckReadyStatesetTimeout

document.readyState === "complete"इसका मतलब है कि दस्तावेज़ पूरी तरह से सभी संसाधनों ( https://html.spec.whatwg.org/multipage/dom.html#current-document-readiness ) से भरा हुआ है ।


4
setTimeout बनाम setInterval पर टिप्पणी बहुत अच्छी है।
गल ब्राच

1
readyStateकेवल एक बार DOM पूरी तरह से लोड हो जाने के बाद ट्रिगर होगा, हालाँकि कोई भी <iframe>तत्व अभी भी लोड हो रहा है, इसलिए यह वास्तव में मूल प्रश्न का उत्तर नहीं देता है
CodingIntrigue

1
@rgraham यह आदर्श नहीं है, लेकिन मुझे लगता है कि हम केवल इन रेंडरर्स के साथ इतना ही कर सकते हैं। ऐसे किनारे मामले होने जा रहे हैं जहाँ आपको पता ही नहीं चलेगा कि कुछ पूरी तरह से भरा हुआ है। उस पृष्ठ के बारे में सोचें, जहाँ सामग्री में देरी हो रही है, एक या दो मिनट के लिए। आस-पास बैठने और समय की अनिश्चित राशि की प्रतीक्षा करने के लिए रेंडर प्रक्रिया की अपेक्षा करना अनुचित है। वही बाहरी स्रोतों से लोड की गई सामग्री के लिए जाता है जो धीमा हो सकता है।
ब्रैंडन इलियट

3
यह DOM के पूरी तरह लोड होने के बाद किसी भी जावास्क्रिप्ट लोडिंग पर विचार नहीं करता है, जैसे कि Backbone / Ember / Angular के साथ।
एडम थॉम्पसन

1
मेरे लिए बिल्कुल काम नहीं किया। रेडीस्टेट पूरा हो सकता है अच्छी तरह से निकाल दिया गया है, लेकिन इस बिंदु पर पृष्ठ खाली था।
स्टीव स्टैपल

21

आप वेटफोर के संयोजन का प्रयास कर सकते हैं और उदाहरणों को व्यवस्थित कर सकते हैं:

/**
 * See https://github.com/ariya/phantomjs/blob/master/examples/waitfor.js
 * 
 * Wait until the test condition is true or a timeout occurs. Useful for waiting
 * on a server response or for a ui change (fadeIn, etc.) to occur.
 *
 * @param testFx javascript condition that evaluates to a boolean,
 * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
 * as a callback function.
 * @param onReady what to do when testFx condition is fulfilled,
 * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
 * as a callback function.
 * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
 */
function waitFor(testFx, onReady, timeOutMillis) {
    var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
        start = new Date().getTime(),
        condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()), //< defensive code
        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(), system = require('system'), address, output, size;

if (system.args.length < 3 || system.args.length > 5) {
    console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
    console.log('  paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
    phantom.exit(1);
} else {
    address = system.args[1];
    output = system.args[2];
    if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
        size = system.args[3].split('*');
        page.paperSize = size.length === 2 ? {
            width : size[0],
            height : size[1],
            margin : '0px'
        } : {
            format : system.args[3],
            orientation : 'portrait',
            margin : {
                left : "5mm",
                top : "8mm",
                right : "5mm",
                bottom : "9mm"
            }
        };
    }
    if (system.args.length > 4) {
        page.zoomFactor = system.args[4];
    }
    var resources = [];
    page.onResourceRequested = function(request) {
        resources[request.id] = request.stage;
    };
    page.onResourceReceived = function(response) {
        resources[response.id] = response.stage;
    };
    page.open(address, function(status) {
        if (status !== 'success') {
            console.log('Unable to load the address!');
            phantom.exit();
        } else {
            waitFor(function() {
                // Check in the page if a specific element is now visible
                for ( var i = 1; i < resources.length; ++i) {
                    if (resources[i] != 'end') {
                        return false;
                    }
                }
                return true;
            }, function() {
               page.render(output);
               phantom.exit();
            }, 10000);
        }
    });
}

3
ऐसा लगता है कि यह वेब पेज के साथ काम नहीं करेगा, जो कि सर्वर पुश प्रौद्योगिकियों में से किसी का उपयोग करता है, क्योंकि संसाधन अभी भी ऑनऑलड के बाद उपयोग में होंगे।
nilfalse

किसी भी ड्राइवर, जैसे। poltergeist , इस तरह की सुविधा है?
जेरेड बेक बेक

क्या संपूर्ण HTML पाठ को प्रदूषित करने और परिभाषित कीवर्ड की खोज करने के लिए WaitFor का उपयोग करना संभव है? मैंने इसे लागू करने की कोशिश की, लेकिन ऐसा लगता है कि मतदान नवीनतम डाउनलोड किए गए HTML स्रोत को ताज़ा नहीं करता है।
fpdragon

14

शायद आप अतुल्यकालिक लोडिंग का पता लगाने के लिए onResourceRequestedऔर onResourceReceivedकॉलबैक का उपयोग कर सकते हैं । यहाँ उनके प्रलेखन से उन कॉलबैक का उपयोग करने का एक उदाहरण है :

var page = require('webpage').create();
page.onResourceRequested = function (request) {
    console.log('Request ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function (response) {
    console.log('Receive ' + JSON.stringify(response, undefined, 4));
};
page.open(url);

इसके अलावा, आप examples/netsniff.jsएक काम करने वाले उदाहरण के लिए देख सकते हैं ।


लेकिन इस मामले में मैं एक समय में एक से अधिक पेज लोड करने के लिए फैंटमजस के एक उदाहरण का उपयोग नहीं कर सकता, सही?
nilfalse

AJAX / क्रॉस डोमेन अनुरोधों पर onResourceRequested लागू होता है? या यह केवल सीएसएस, चित्र .. आदि को पसंद करने के लिए लागू होता है?
CMCDragonkai 8:24 बजे

@CMCDragonkai मैं इसे अपने आप का इस्तेमाल किया है कभी नहीं, लेकिन के आधार पर यह ऐसा लगता है जैसे कि यह सभी अनुरोधों को भी शामिल है। Quote:All the resource requests and responses can be sniffed using onResourceRequested and onResourceReceived
सुपर

मैंने इस विधि का उपयोग बड़े पैमाने पर PhantomJS प्रतिपादन के साथ किया है और यह काफी अच्छी तरह से काम करता है। अनुरोधों को ट्रैक करने और देखने में विफल या समय समाप्त होने पर आपको बहुत से स्मार्ट की आवश्यकता होती है। अधिक जानकारी: sorcery.smugmug.com/2013/12/17/using-phantomjs-at-scale
रायन डोहर्टी

14

यहां एक समाधान है जो सभी संसाधन अनुरोधों को पूरा करने के लिए इंतजार करता है। एक बार पूरा होने पर यह पेज कंटेंट को कंसोल में लॉग करेगा और रेंडर किए गए पेज का स्क्रीनशॉट जेनरेट करेगा।

हालाँकि यह समाधान एक अच्छे शुरुआती बिंदु के रूप में काम कर सकता है, लेकिन मैंने देखा है कि यह विफल रहा है इसलिए यह निश्चित रूप से पूर्ण समाधान नहीं है!

मैं बहुत किस्मत का उपयोग नहीं किया था document.readyState

मैं प्रेत के उदाहरण पृष्ठ पर पाए गए वफ़र.जे के उदाहरण से प्रभावित था ।

var system = require('system');
var webPage = require('webpage');

var page = webPage.create();
var url = system.args[1];

page.viewportSize = {
  width: 1280,
  height: 720
};

var requestsArray = [];

page.onResourceRequested = function(requestData, networkRequest) {
  requestsArray.push(requestData.id);
};

page.onResourceReceived = function(response) {
  var index = requestsArray.indexOf(response.id);
  requestsArray.splice(index, 1);
};

page.open(url, function(status) {

  var interval = setInterval(function () {

    if (requestsArray.length === 0) {

      clearInterval(interval);
      var content = page.content;
      console.log(content);
      page.render('yourLoadedPage.png');
      phantom.exit();
    }
  }, 500);
});

एक थम्स-अप दिया, लेकिन अंतराल के बजाय 10 के साथ
सेटटाइमआउट

आपको यह देखना चाहिए कि अनुरोध सरणी से हटाने से पहले response.stage 'अंत' के बराबर है, अन्यथा इसे समय से पहले हटाया जा सकता है।
रीमुंड

यह काम नहीं करता है यदि आपका वेबपेज डोम को गतिशील रूप से लोड करता है
बडी

13

अपने कार्यक्रम में, मैं कुछ तर्क का उपयोग करता हूं अगर यह ऑनलोड होता है: यह नेटवर्क अनुरोध देख रहा है, अगर पिछले 200ms पर कोई नया अनुरोध नहीं था, तो मैं इसे ऑनलोड मानता हूं।

OnLoadFinish () के बाद इसका उपयोग करें।

function onLoadComplete(page, callback){
    var waiting = [];  // request id
    var interval = 200;  //ms time waiting new request
    var timer = setTimeout( timeout, interval);
    var max_retry = 3;  //
    var counter_retry = 0;

    function timeout(){
        if(waiting.length && counter_retry < max_retry){
            timer = setTimeout( timeout, interval);
            counter_retry++;
            return;
        }else{
            try{
                callback(null, page);
            }catch(e){}
        }
    }

    //for debug, log time cost
    var tlogger = {};

    bindEvent(page, 'request', function(req){
        waiting.push(req.id);
    });

    bindEvent(page, 'receive', function (res) {
        var cT = res.contentType;
        if(!cT){
            console.log('[contentType] ', cT, ' [url] ', res.url);
        }
        if(!cT) return remove(res.id);
        if(cT.indexOf('application') * cT.indexOf('text') != 0) return remove(res.id);

        if (res.stage === 'start') {
            console.log('!!received start: ', res.id);
            //console.log( JSON.stringify(res) );
            tlogger[res.id] = new Date();
        }else if (res.stage === 'end') {
            console.log('!!received end: ', res.id, (new Date() - tlogger[res.id]) );
            //console.log( JSON.stringify(res) );
            remove(res.id);

            clearTimeout(timer);
            timer = setTimeout(timeout, interval);
        }

    });

    bindEvent(page, 'error', function(err){
        remove(err.id);
        if(waiting.length === 0){
            counter_retry = 0;
        }
    });

    function remove(id){
        var i = waiting.indexOf( id );
        if(i < 0){
            return;
        }else{
            waiting.splice(i,1);
        }
    }

    function bindEvent(page, evt, cb){
        switch(evt){
            case 'request':
                page.onResourceRequested = cb;
                break;
            case 'receive':
                page.onResourceReceived = cb;
                break;
            case 'error':
                page.onResourceError = cb;
                break;
            case 'timeout':
                page.onResourceTimeout = cb;
                break;
        }
    }
}

11

मुझे यह दृष्टिकोण कुछ मामलों में उपयोगी लगा:

page.onConsoleMessage(function(msg) {
  // do something e.g. page.render
});

यदि आप पृष्ठ के अंदर से कुछ स्क्रिप्ट रखते हैं, तो:

<script>
  window.onload = function(){
    console.log('page loaded');
  }
</script>

यह वास्तव में बहुत अच्छा काम करता है। हालांकि, मुझे अपने HTML / जावास्क्रिप्ट पृष्ठ से कोई भी संदेश नहीं मिल सकता है ताकि phantomJS से गुजर सकें ... onConsoleMessage घटना कभी ट्रिगर नहीं हुई, जबकि मैं ब्राउज़र कंसोल पर संदेशों को पूरी तरह से देख सकता था, और मेरे पास कोई सुराग नहीं है क्यों।
डिर्क

1
मुझे page.onConsoleMessage = function (msg) {} की आवश्यकता थी;
एंडी बालाम

5

मुझे यह समाधान NodeJS ऐप में उपयोगी लगा। मैं इसे केवल हताश मामलों में उपयोग करता हूं क्योंकि यह पूर्ण पृष्ठ लोड की प्रतीक्षा करने के लिए एक समयबाह्य लॉन्च करता है।

दूसरा तर्क कॉलबैक फ़ंक्शन है जिसे प्रतिक्रिया तैयार होने के बाद कॉल किया जाएगा।

phantom = require('phantom');

var fullLoad = function(anUrl, callbackDone) {
    phantom.create(function (ph) {
        ph.createPage(function (page) {
            page.open(anUrl, function (status) {
                if (status !== 'success') {
                    console.error("pahtom: error opening " + anUrl, status);
                    ph.exit();
                } else {
                    // timeOut
                    global.setTimeout(function () {
                        page.evaluate(function () {
                            return document.documentElement.innerHTML;
                        }, function (result) {
                            ph.exit(); // EXTREMLY IMPORTANT
                            callbackDone(result); // callback
                        });
                    }, 5000);
                }
            });
        });
    });
}

var callback = function(htmlBody) {
    // do smth with the htmlBody
}

fullLoad('your/url/', callback);

3

यह Supr के उत्तर का कार्यान्वयन है। इसके अलावा यह सेटटाइटर के बजाय सेटटाइमआउट का उपयोग करता है जैसा कि माटेउसज़ चेरिटोनियुक ने सुझाया था।

जब कोई अनुरोध या प्रतिक्रिया नहीं होती है, तो प्रेत 1000 मीटर से बाहर निकल जाएंगे।

// load the module
var webpage = require('webpage');
// get timestamp
function getTimestamp(){
    // or use Date.now()
    return new Date().getTime();
}

var lastTimestamp = getTimestamp();

var page = webpage.create();
page.onResourceRequested = function(request) {
    // update the timestamp when there is a request
    lastTimestamp = getTimestamp();
};
page.onResourceReceived = function(response) {
    // update the timestamp when there is a response
    lastTimestamp = getTimestamp();
};

page.open(html, function(status) {
    if (status !== 'success') {
        // exit if it fails to load the page
        phantom.exit(1);
    }
    else{
        // do something here
    }
});

function checkReadyState() {
    setTimeout(function () {
        var curentTimestamp = getTimestamp();
        if(curentTimestamp-lastTimestamp>1000){
            // exit if there isn't request or response in 1000ms
            phantom.exit();
        }
        else{
            checkReadyState();
        }
    }, 100);
}

checkReadyState();

3

यह कोड मैं उपयोग करता हूं:

var system = require('system');
var page = require('webpage').create();

page.open('http://....', function(){
      console.log(page.content);
      var k = 0;

      var loop = setInterval(function(){
          var qrcode = page.evaluate(function(s) {
             return document.querySelector(s).src;
          }, '.qrcode img');

          k++;
          if (qrcode){
             console.log('dataURI:', qrcode);
             clearInterval(loop);
             phantom.exit();
          }

          if (k === 50) phantom.exit(); // 10 sec timeout
      }, 200);
  });

मूल रूप से इस तथ्य को देखते हुए कि आप यह जानना चाहते हैं कि DOM पर किसी दिए गए तत्व के दिखाई देने पर पेज पूरा डाउनलोड हो जाता है। इसलिए स्क्रिप्ट ऐसा होने तक इंतजार करने वाली है।


3

मैं फैंटमज waitfor.jsउदाहरण के एक व्यक्ति मिश्रण का उपयोग करता हूं ।

यह मेरी main.jsफाइल है:

'use strict';

var wasSuccessful = phantom.injectJs('./lib/waitFor.js');
var page = require('webpage').create();

page.open('http://foo.com', function(status) {
  if (status === 'success') {
    page.includeJs('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js', function() {
      waitFor(function() {
        return page.evaluate(function() {
          if ('complete' === document.readyState) {
            return true;
          }

          return false;
        });
      }, function() {
        var fooText = page.evaluate(function() {
          return $('#foo').text();
        });

        phantom.exit();
      });
    });
  } else {
    console.log('error');
    phantom.exit(1);
  }
});

और lib/waitFor.jsफ़ाइल (जो waifFor()कि फैंटमज waitfor.jsउदाहरण से फ़ंक्शन की कॉपी और पेस्ट है ):

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 condi>
                    clearInterval(interval); //< Stop this interval
                }
            }
        }, 250); //< repeat check every 250ms
}

यह विधि अतुल्यकालिक नहीं है, लेकिन कम से कम मुझे आश्वासन दिया गया है कि सभी संसाधनों को लोड करने से पहले मैं उनका उपयोग करने की कोशिश कर रहा हूं।


2

यह एक पुराना प्रश्न है, लेकिन जब से मैं पूर्ण पृष्ठ लोड की तलाश कर रहा था, लेकिन स्पूकीज के लिए (जो कास्परज और फैंटमज का उपयोग करता है) और मुझे अपना समाधान नहीं मिला, मैंने इसके लिए अपनी स्क्रिप्ट बनाई, उसी के साथ उपयोगकर्ता डीमस्टोन के रूप में। यह दृष्टिकोण क्या करता है, एक निश्चित समय के लिए, यदि पृष्ठ प्राप्त नहीं हुआ या किसी भी अनुरोध को शुरू नहीं किया गया तो यह निष्पादन को समाप्त कर देगा।

Casper.js फ़ाइल पर (यदि आपने इसे विश्व स्तर पर स्थापित किया है, तो पथ कुछ इस तरह होगा /usr/local/lib/node_modules/casperjs/modules/casper.js) निम्न पंक्तियाँ जोड़ें:

सभी वैश्विक संस्करणों के साथ फ़ाइल के शीर्ष पर:

var waitResponseInterval = 500
var reqResInterval = null
var reqResFinished = false
var resetTimeout = function() {}

फिर फंक्शन के अंदर "createPage (केस्पर)" के बाद "var पेज = आवश्यकता ('वेबपेज'); create ();" निम्नलिखित कोड जोड़ें:

 resetTimeout = function() {
     if(reqResInterval)
         clearTimeout(reqResInterval)

     reqResInterval = setTimeout(function(){
         reqResFinished = true
         page.onLoadFinished("success")
     },waitResponseInterval)
 }
 resetTimeout()

फिर पहली पंक्ति में "page.onResourceReceived = function onResourceReceived (संसाधन) {" के अंदर:

 resetTimeout()

"Page.onResourceRequested = function onResourceRequested (requestData, request) {" के लिए समान कार्य करें

अंत में, पहली पंक्ति में "page.onLoadFinished = function onLoadFinished (स्थिति) {" पर:

 if(!reqResFinished)
 {
      return
 }
 reqResFinished = false

और यह बात है, आशा है कि यह किसी को मुसीबत में मदद करता है जैसे मैं था। यह समाधान कैस्परज के लिए है, लेकिन स्पूकी के लिए सीधे काम करता है।

सौभाग्य !


0

यह मेरा समाधान है जो मेरे लिए काम करता है।

page.onConsoleMessage = function(msg, lineNum, sourceId) {

    if(msg=='hey lets take screenshot')
    {
        window.setInterval(function(){      
            try
            {               
                 var sta= page.evaluateJavaScript("function(){ return jQuery.active;}");                     
                 if(sta == 0)
                 {      
                    window.setTimeout(function(){
                        page.render('test.png');
                        clearInterval();
                        phantom.exit();
                    },1000);
                 }
            }
            catch(error)
            {
                console.log(error);
                phantom.exit(1);
            }
       },1000);
    }       
};


page.open(address, function (status) {      
    if (status !== "success") {
        console.log('Unable to load url');
        phantom.exit();
    } else { 
       page.setContent(page.content.replace('</body>','<script>window.onload = function(){console.log(\'hey lets take screenshot\');}</script></body>'), address);
    }
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.