2012-10-03 24 views
21

के बाद केवल फ़ैंटॉमजेएस स्क्रिप्ट को समाप्त करने के लिए कैसे करें I मेरा एक प्रोजेक्ट (वर्तमान में संस्करण 1.6 का उपयोग करके) में फैंटॉमजेएस हेडलेस ब्राउज़र को एकीकृत करने पर काम कर रहा हूं। अधिकांश भाग के लिए, यह पूरा करने में मुझे एक महान काम कर रहा है कि मुझे पूरा करने की आवश्यकता है। हालांकि, WebPage.open() कॉल करने के तरीके की असीमित प्रकृति, और किसी बिंदु पर phantom.exit() को कॉल करने की आवश्यकता, क्लाइंट साइड रीडायरेक्ट को संभालने में मुश्किल होती है जब आप यह अनुमान नहीं लगा सकते कि वे कहां जा रहे हैं जाना।क्लाइंट-साइड रीडायरेक्ट्स

मैं जो भी कर रहा हूं वह किसी भी मेटा रीफ्रेश (जो एक अलग पृष्ठ पर जाता है) के बाद केवल phantom.exit() को कॉल करने का एक तरीका है और ऑनलोड ईवेंट जैसी चीजों से जुड़ा जावास्क्रिप्ट रीडायरेक्ट निष्पादित किया गया है। मैं देख सकता हूं कि यह एक मुद्दा क्यों है, क्योंकि सिद्धांत में क्लाइंट साइड रीडायरेक्ट पेज लोड के बाद किसी भी सेकेंड में हो सकता है, और मैं केवल तब बाहर निकलने की क्षमता नहीं मांग सकता जब रीडायरेक्ट नहीं होता जगह लें। अभी, सबसे अच्छा समाधान मैं सोच सकता हूं कि ए) पृष्ठ पर मेटा रीफ्रेश तत्वों की उपस्थिति का मैन्युअल रूप से पता लगाता है और उन लोगों से निपटता है, और बी) कुछ निश्चित समय की अनुमति देने के लिए setInterval() का उपयोग करें (कहें, 1- 1.5 सेकंड) phantom.exit() को कॉल करने से पहले elapse करने के लिए। यह मूल रूप से इस तरह दिखता है:

var page = require('webpage').create(); 
var visitComplete = false; 
var url = "http://some.url"; 
var pageOpenedTime; 
setInterval(function() { 
    if (visitcomplete && typeof pageOpenedTime != 'undefined' && 
     new Date() - pageOpenedTime >= 1500) 
    { 
     phantom.exit(); 
    } 
), 1000); 
page.open(url, function() { 
    pageOpenedTime = new Date(); 
    if (!hasMetaRefresh(page)) { 
     visitComplete = true; 
    } 
}); 

function hasMetaRefresh(page) { 
    // Query the DOM here to detect meta refresh elements 
} 

कोई बेहतर विचार?

संपादित करें: मुझे यह उल्लेख करना चाहिए कि मेरा पहला विचार यह था कि प्रारंभिक पृष्ठ लोड से जुड़े जावास्क्रिप्ट को निष्पादित करते समय एक फैंटॉमजेएस घटना हो सकती है, लेकिन ऑनलोड लोड कॉलबैक किसी भी इन-इन के निष्पादन से पहले प्रतीत होता है। ऑनलोड घटनाओं सहित पेज जावास्क्रिप्ट। मैंने कुछ परीक्षण किए हैं कि मुझे कितने अंतराल की प्रतीक्षा करनी पड़ सकती है, और एक छोटे से परीक्षण पृष्ठ में निष्पादित करने के लिए जावास्क्रिप्ट रीडायरेक्ट (बॉडी ऑनलोड इवेंट के माध्यम से) के लिए 1000 एमएस काफी लंबा था, 100 एमएस काफी लंबा नहीं था।

+0

मैंने अपनी परियोजना में एक ही दृष्टिकोण का उपयोग किया, यानी।कॉल के बीच थोड़ा विराम जोड़ा गया। मुझे डर है कि यह एकमात्र विकल्प है (अभी के लिए)। –

उत्तर

0

मेरे पास इस उद्देश्य के लिए मॉक टाइमर का उपयोग करने का विचार है। मान लें कि हम पृष्ठ में "a mocked timer" शामिल हैं। इस तरह, आप जेएस निष्क्रिय समय से बचने के लिए समय-समय पर आगे बढ़ सकते हैं। गिटहब पेज पर उदाहरण देखें।

यह चीजों को तेजी से करने के लिए एक दृष्टिकोण है, लेकिन जैसा कि आप उम्मीद करेंगे, यह सुनिश्चित करना संभव नहीं है कि भविष्य में एक पुनर्निर्देशन समारोह निकाल दिया जाएगा या नहीं।

8

मेरे पास एक ऐसा पृष्ठ लोड हो रहा है जो ऑप्टिमाइज़ली का उपयोग कर रहा था, और विविधता एक स्थान था। रेफरी रीडायरेक्ट।

अब मैं "renderPage" फ़ंक्शन के अंदर ऑनविगेशन रिवेस्ट कॉलबैक का उपयोग करता हूं। वे ऑप्टिमाइज़ रीडायरेक्ट अब ब्लॉक नहीं करते हैं और मुझे मनमाने ढंग से टाइमआउट की आवश्यकता नहीं है। http://phantomjs.org/api/webpage/handler/on-navigation-requested.html

+0

यह हेडर रीडायरेक्ट, जेएस रीडायरेक्ट और उपयोगकर्ता क्रियाओं के लिए सही होगा? – CMCDragonkai

+0

@CMCDragonkai: मेरे उपयोग के अनुसार यह यूआरएल में किसी भी बदलाव पर काम करता है - इसलिए हमें 302 -> ब्राउज़र प्राप्त होता है - यह नया अनुरोध करता है -> नेविगेशन परिवर्तन यदि आप कोई स्थान करते हैं तो जावास्क्रिप्ट के माध्यम से एक ही चीज़ है। प्रयोक्ता क्रियाएं (यानी, नकली माउसक्लिक्स और फॉर्मबमिट आदि का अलग-अलग व्यवहार किया जाता है: परिवर्तन के साथ "प्रकार" मान (प्रकार: संभावित मानों में शामिल हैं: 'अपरिभाषित', 'लिंकक्लेटेड', 'फॉर्म सबमिट', 'बैकऑरफ़ोर्ड', 'रीलोड', 'फॉर्म रेसबमिट' , 'अन्य') – ProfessionalHack

0

मैं पहले से ही चेकआउट phantomjs के लिए उदाहरण के विभिन्न अनुप्रेषित हैंडलिंग: कठिन भाग्य

var webpage = require('webpage'); 
var page = null; 

var renderPage = function (myurl) { 
    page = webpage.create(); 

    page.onNavigationRequested = function(url, type, willNavigate, main) { 
     if (main && url!=myurl && url.replace(/\/$/,"")!=myurl&& (type=="Other" || type=="Undefined")) { 
     // main = navigation in main frame; type = not by click/submit etc 

      log("\tfollowing "+myurl+" redirect to "+url) 
      myurl = url; 
      page.close(); 
      renderPage(url); // rerun this function wit the new URL 
     } 
    }; // on Nav req 

    page.open(myurl, function(status) { 
     if (status==="success") { 
      page.render("screenshot.jpg"); 
     } else { 
      page.close(); 
     } 
    }); // page open 
} // render page 


renderPage("http://some.domain.com"); 

दस्तावेज़ देख सकेंगे।

समय के लिए, इसके लिए कोई सार्वभौमिक समाधान नहीं है। यदि आप कुछ स्क्रिप्ट as suggested here पैच करते हैं, तो यह अन्य परिदृश्य के तहत विफल हो जाएगा, उदा। रीडायरेक्ट करने के लिए जावास्क्रिप्ट का उपयोग करते हुए location.href का उपयोग करने के बगल में। मैंने अभी तक शरीर का परीक्षण नहीं किया है। यहाँ और वहां पैचिंग के कुछ पैसे बाद, मैं हार मानता हूं।

मैं अपने मुद्दों को हल करने के लिए "भारी" सेलेनियम ट्रिगर फ़ायरफ़ॉक्स का उपयोग करता हूं। यदि आपको फ़ायरफ़ॉक्स को पुनरारंभ करने के बजाय कई पेज लोड करने की आवश्यकता है, तो कुछ पकड़ को साफ करने के लिए बस webdriver.delete_all_cookies() का उपयोग करें। यह मुझे विश्वसनीय परिणाम देता है (जो मुझे स्क्रीन कैप्चर करने, एचटीएमएल डाउनलोड करने, अंतिम यूआरएल प्राप्त करने की आवश्यकता है, और बहुत कुछ) phantomjs की तुलना करें।

संबंधित मुद्दे