2011-06-12 8 views
5

मेरे पास एक सी # ऐप है जिसे जितना संभव हो सके एक निश्चित डोमेन के भीतर कई सारे पृष्ठों को स्क्रैप करने की आवश्यकता है। मैं एक Parallel.Foreach कि यूआरएल (मल्टी-थ्रेडेड) और उन्हें खरोंच के सभी के माध्यम से लूप नीचे कोड का उपयोग कर:वेब पृष्ठों को एक वेब साइट के भीतर स्क्रैप करने का सबसे तेज़ तरीका

private string ScrapeWebpage(string url, DateTime? updateDate) 
     { 
      HttpWebRequest request = null; 
      HttpWebResponse response = null; 
      Stream responseStream = null; 
      StreamReader reader = null; 
      string html = null; 

      try 
      { 
       //create request (which supports http compression) 
       request = (HttpWebRequest)WebRequest.Create(url); 
       request.Pipelined = true; 
       request.KeepAlive = true; 
       request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate"); 
       if (updateDate != null) 
        request.IfModifiedSince = updateDate.Value; 

       //get response. 
       response = (HttpWebResponse)request.GetResponse(); 
       responseStream = response.GetResponseStream(); 
       if (response.ContentEncoding.ToLower().Contains("gzip")) 
        responseStream = new GZipStream(responseStream, CompressionMode.Decompress); 
       else if (response.ContentEncoding.ToLower().Contains("deflate")) 
        responseStream = new DeflateStream(responseStream, CompressionMode.Decompress); 

       //read html. 
       reader = new StreamReader(responseStream, Encoding.Default); 
       html = reader.ReadToEnd(); 
      } 
      catch 
      { 
       throw; 
      } 
      finally 
      {//dispose of objects. 
       request = null; 
       if (response != null) 
       { 
        response.Close(); 
        response = null; 
       } 
       if (responseStream != null) 
       { 
        responseStream.Close(); 
        responseStream.Dispose(); 
       } 
       if (reader != null) 
       { 
        reader.Close(); 
        reader.Dispose(); 
       } 
      } 
      return html; 
     } 

आप देख सकते हैं, मैं http संपीड़न समर्थन है और request.keepalive की स्थापना की है और request.pipelined सच करने के लिए। मैं सोच रहा हूं कि यदि मैं जिस कोड का उपयोग कर रहा हूं वह एक ही साइट के भीतर कई वेब पृष्ठों को स्क्रैप करने का सबसे तेज़ तरीका है या यदि कोई बेहतर तरीका है जो सत्र को कई अनुरोधों के लिए खुला रखेगा। मेरा कोड प्रत्येक पृष्ठ पर हिट करने के लिए एक नया अनुरोध उदाहरण बना रहा है, क्या मुझे सभी पृष्ठों को हिट करने के लिए केवल एक अनुरोध उदाहरण का उपयोग करने की कोशिश करनी चाहिए? क्या पाइपलाइन और रखरखाव सक्षम होना आदर्श है?

+0

"के रूप में तेजी से संभव के रूप में स्क्रेप" - ध्यान दें कि जब तक आप साइट के मालिक के साथ कुछ समझौता है, यह हो आप जितनी जल्दी संभव हो पर प्रतिबंध लगा दिया जाएगा; कोई भी अनधिकृत स्क्रैपर्स पसंद नहीं करता है, खासकर यदि वे एक अनपेक्षित डीओएस भी हैं (और प्रत्येक अनुरोध के लिए एक नया कनेक्शन खोलना कई सर्वरों को खत्म कर सकता है) – Piskvor

+0

बिंदु पर: हाँ, रखरखाव और पाइपलाइनिंग आपको बेहतर प्रदर्शन प्रदान करेगी (क्योंकि कम सेटअप/टियरडाउन ओवरहेड)। – Piskvor

+0

हां निश्चित रूप से, यह रडार के नीचे रहने के लिए बहुत अधिक स्क्रैपिंग के साथ हमेशा एक अच्छी रेखा है लेकिन आपके डेटा को अद्यतित रखने के लिए पर्याप्त तेज़ है। HttpWebRequest ऑब्जेक्ट में 100 सेकंड का डिफ़ॉल्ट टाइमआउट होता है, मैंने इसे 10 सेकंड तक सेट किया और फिर टाइमआउट का एक टन प्राप्त हो रहा था। मुझे एहसास हुआ कि कुछ अस्वस्थ था, फिर 10 से 100 के लिए डिफ़ॉल्ट कनेक्शन सीमा बदल दी और उसने सभी टाइमआउट को हल किया और अब सभी वेब अनुरोध सुपर फास्ट हैं .. बहुत तेज .. मुझे अब इसे थ्रॉटल करना होगा। :) – Justin

उत्तर

1

यह पता चला है कि मैं क्या याद आ रही थी था इस:

ServicePointManager.DefaultConnectionLimit = 1000000; 
+0

क्या आप अपनी पोस्ट को उत्तर के रूप में चिह्नित कर सकते हैं, मैं' डी यह जानना पसंद है कि आप इस फ़ंक्शन का उपयोग कैसे करते हैं ताकि यह ज़िंदा रह सके? – Smith

+0

क्या आप उदाहरण दे सकते हैं कि आप इस फ़ंक्शन का उपयोग बाद की कॉल के बीच कैसे करते हैं ताकि वह जीवित रहे? – Smith

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