2011-06-12 21 views
5

Belirli bir alanda çok sayıda sayfayı mümkün olduğunca hızlı bir şekilde kazımaya ihtiyaç duyan bir C# uygulamasına sahibim. Ben aşağıdaki kodu kullanarak URL'ler (çok kanallı) ve çiziklere hepsi aracılığıyla döngüler bir Parallel.Foreach vardır:Web sayfalarını tek bir web sitesi içinde en hızlı şekilde kazımak için en hızlı yol

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

Gördüğünüz gibi, ben http sıkıştırma desteği ve request.keepalive belirledik ve request.pipelined true. Kullanmakta olduğum kodun, aynı sitedeki birçok web sayfasını ya da birden fazla istek için açık oturumun daha açık olmasını sağlayacak daha iyi bir yol varsa en hızlı yol olup olmadığını merak ediyorum. Kodum, tüm sayfaları vurmak için yalnızca bir istek örneğini kullanmaya çalışmam gerektiğinde, vurduğum her sayfa için yeni bir istek örneği oluşturuyor? Boru hattına sahip ve kalıcılığa sahip olmak ideal mi?

+0

"mümkün olduğunca hızlı kazımak" - Eğer site sahibi ile bazı anlaşma olmadıkça bu mümkün olduğunca çabuk yasak olsun unutmayın; kimsenin yetkisiz kazıyıcıları sevmemesi, özellikle de istemeden bir DoS olması (ve her istek için yeni bir bağlantı açmak birçok sunucuya zarar verebilir) – Piskvor

+0

Şuna kadar: evet, bekletici ve pipelining size daha iyi bir performans getirecektir (teardown yükü. – Piskvor

+0

Evet, her zaman radarın altında kalmak için değil, verilerinizi güncel tutabilmek için yeterince hızlı değil, kazıma ile her zaman ince bir çizgi. HttpWebRequest nesnesinin 100 saniyelik bir zaman aşımı var, 10 saniyeye ayarlıyorum ve bir ton zaman aşımı oluyordu. Bir şeylerin yanlış olduğunu farkettim, sonra 10'dan 100K'ya kadar olan varsayılan bağlantı limitini değiştirdim ve tüm zaman aşımlarını çözdü ve şimdi tüm web istekleri süper hızlı .. çok hızlı .. Şimdi bunu kısmaya ihtiyacım var. :) – Justin

cevap

1

Ben bu oldu ne eksikti çıkıyor:

ServicePointManager.DefaultConnectionLimit = 1000000; 
+0

yazınızı yanıt olarak işaretleyebilir misiniz?' Bu işlevi nasıl kullandığınızı bilmek, böylece canlı tutmayı destekliyor mu? – Smith

+0

Bu işlevi, sonraki aramalar arasında nasıl canlı tuttuğunuzu gösterecek şekilde örnek verebilir misiniz? – Smith

İlgili konular