2011-04-05 12 views
19

के लिए प्रतीक्षा नहीं करता है मेरे पास एक GWT आधारित पृष्ठ है जिसे मैं HtmlUnit का उपयोग कर इसके लिए एक HTML स्नैपशॉट बनाना चाहता हूं। पृष्ठ किसी उत्पाद पर अजाक्स/जावास्क्रिप्ट जानकारी का उपयोग करके लोड करता है, इसलिए लगभग 1 सेकंड के लिए लोड हो रहा है ... संदेश और फिर सामग्री प्रकट होती है।HTMLUnit जावास्क्रिप्ट

समस्या यह है कि HtmlUnit जानकारी को कैप्चर नहीं कर रहा है और मुझे जो कुछ मिल रहा है वह "लोड हो रहा है ..." अवधि है।

नीचे एचटीएमएलयूनीट के साथ एक प्रयोगात्मक कोड है जहां मैं डेटा लोड करने की प्रतीक्षा करने के लिए पर्याप्त समय देने की कोशिश करता हूं लेकिन ऐसा कुछ भी नहीं लगता है और मैं अभी भी जीडब्ल्यूटी जावास्क्रिप्ट द्वारा लोड किए गए डेटा को कैप्चर करने में असमर्थ हूं ।

 WebClient webClient = new WebClient(); 
     webClient.setJavaScriptEnabled(true); 
     webClient.setThrowExceptionOnScriptError(false); 
     webClient.setAjaxController(new NicelyResynchronizingAjaxController()); 

     WebRequest request = new WebRequest(new URL("<my_url>")); 
     HtmlPage page = webClient.getPage(request); 

     int i = webClient.waitForBackgroundJavaScript(1000); 

     while (i > 0) 
     { 
      i = webClient.waitForBackgroundJavaScript(1000); 

      if (i == 0) 
      { 
       break; 
      } 
      synchronized (page) 
      { 
       System.out.println("wait"); 
       page.wait(500); 
      } 
     } 

     webClient.getAjaxController().processSynchron(page, request, false); 

     System.out.println(page.asXml()); 

कोई विचार ...?

उत्तर

18

जवाब के लिए धन्यवाद। मुझे वास्तव में यह जल्द ही सूचित करना चाहिए था कि मुझे स्वयं समाधान मिला है। एफएफ के साथ जाहिर है जब initialising WebClient:

WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6); 

यह काम करने लगते हैं। डिफ़ॉल्ट कन्स्ट्रक्टर के साथ वेब क्लाइंट प्रारंभ करते समय यह डिफ़ॉल्ट रूप से आई 7 का उपयोग करता है और मुझे लगता है कि एफएफ के पास अजाक्स के लिए बेहतर समर्थन है और उपयोग करने के लिए अनुशंसित एमुलेटर है।

+1

मुझे यह टिप्पणी करना है। एक ही समस्या थी और पूरे कोड को डीबग करने की कोशिश कर रहा था .. इसके लिए बहुत बहुत धन्यवाद। –

+0

हाय। आईई के बावजूद FIREFOX का उपयोग करके मुझे एक ही समस्या है, पेज अब लगभग ठीक से लोड हो जाता है, लेकिन फिर भी मैं अटक गया हूं ... लोड हो रहा है ...संदेश, यह लगभग 9 सेकंड होना चाहिए, कोड के आपके हिस्से का भी उपयोग किया जाना चाहिए और कुछ भी नहीं :(कृपया – silvestrairwave

+0

मदद करें! धन्यवाद, जब तक मुझे आपकी टिप्पणी नहीं मिली, मैंने डीबगिंग पर कई घंटे खो दिए हैं! – kotslon

14

मुझे विश्वास है कि डिफ़ॉल्ट NicelyResynchronizingAjaxController केवल उपयोगकर्ता क्रिया के कारण AJAX कॉल को पुन: सिंक्रनाइज़ करेगा, यह ट्रैक करके कि यह किस धागे से उत्पन्न हुआ था। शायद जीडब्ल्यूटी जेनरेट जावास्क्रिप्ट को किसी अन्य थ्रेड द्वारा बुलाया जा रहा है जो NicelyResynchronizingAjaxController के लिए इंतजार नहीं करना चाहता।

अपनी खुद की AjaxController घोषित उद्भव धागा की परवाह किए बिना सब कुछ के साथ सिंक्रनाइज़ करने का प्रयास:

webClient.setAjaxController(new AjaxController(){ 
    @Override 
    public boolean processSynchron(HtmlPage page, WebRequest request, boolean async) 
    { 
     return true; 
    } 
}); 
1

अब तक उपलब्ध समाधानों में से कोई भी मेरे लिए काम नहीं करता है। मैं Dan Alvizu's solution साथ समाप्त हो गया + मेरे अपने हैक: "कृपया प्रतीक्षा लोड करते समय"

private WebClient webClient = new WebClient(); 

public void scrapPage() { 
    makeWebClientWaitThroughJavaScriptLoadings(); 
    HtmlPage page = login(); 
    //do something that causes JavaScript loading 
    waitOutLoading(page); 
} 

private void makeWebClientWaitThroughJavaScriptLoadings() { 
    webClient.setAjaxController(new AjaxController(){ 
     @Override 
     public boolean processSynchron(HtmlPage page, WebRequest request, boolean async) 
     { 
      return true; 
     } 
    }); 
} 

private void waitOutLoading(HtmlPage page) { 
    while(page.asText().contains("Please wait while loading!")){ 
     webClient.waitForBackgroundJavaScript(100); 
    } 
} 

जरूरत नहीं कहने के लिए, आपका पृष्ठ लोड होने पर जो कुछ भी दिखाया गया है उसके साथ प्रतिस्थापित किया जाना चाहिए। यदि कोई पाठ नहीं है, तो शायद कुछ gif (यदि इसका उपयोग किया जाता है) के अस्तित्व की जांच करने का एक तरीका है। बेशक, यदि आप साहसी महसूस कर रहे हैं तो आप बस एक बड़ा पर्याप्त मिलीसेकंड मूल्य प्रदान कर सकते हैं।

4

प्रलेखन राज्यों के रूप में, waitForBackgroundJavaScript प्रायोगिक है:

प्रायोगिक एपीआई: अगली फिल्म में बदला जा सकता है और अभी तक पूरी तरह से काम नहीं हो सकता!

अगले दृष्टिकोण हमेशा BrowserVersion इस्तेमाल किया की परवाह किए बिना, मेरे लिए काम किया है:

int tries = 5; // Amount of tries to avoid infinite loop 
while (tries > 0 && aCondition) { 
    tries--; 
    synchronized(page) { 
     page.wait(2000); // How often to check 
    } 
} 

नोट aCondition जो कुछ भी आप के लिए जाँच कर रहे हैं है। ईजी:

page.getElementById("loading-text-element").asText().equals("Loading...") 
+1

इस तरह के मतदान ने मेरे लिए अभी तक ठीक काम किया है भी। – MrSmith42

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