2009-10-12 6 views
1

Je suis très nouveau à ce s'il vous plaît pardonnez toute ignorance.source de page partielle de httpwebresponse

J'ai créé ma première application multithread et son but est de faire de nombreuses requêtes, d'analyser chaque source de page et de stocker les résultats dans des tables pour une interrogation plus poussée. Théoriquement, il pourrait y avoir jusqu'à 30-40000 demandes, d'où la nécessité de multi-thread. Chaque requête obtient un fil. Je pense que tout fonctionne, sauf que très souvent je n'ai qu'une source de page très partielle. C'est presque comme si le StreamReader s'interrompait en lisant la réponse. Je vais à un navigateur avec la même demande et obtenir la page entière. Je pensais que cela pourrait avoir à faire avec threading bien que je pense que je fais toujours des appels de manière synchrone. (Idéalement, je voudrais faire les appels de manière asynchrone, mais je ne suis pas sûr de savoir comment procéder.) Y a-t-il un moyen de savoir si la source de la page est complète afin de déterminer si demander à nouveau? Je suis sûr qu'il y a des complexités ici qui me manquent. Toute aide sur n'importe quel code serait grandement appréciée.

Désolé pour le formatage. Ci-dessous fait partie du code de la classe qui fait les demandes:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Data.Sql; 
using System.Data.SqlClient; 
using System.Threading; 
using System.IO; 
using System.Net; 
using System.Text.RegularExpressions; 

namespace M4EverCrawler 
{ 
    public class DomainRun 
    { 
     public void Start() 
     { 
      new Thread(new ThreadStart(this.Run1)).Start(); 

      new Thread(new ThreadStart(this.Run2)).Start(); 

      new Thread(new ThreadStart(this.Run3)).Start(); 
     } 


     public DomainRun(DNQueueManager dnq, ProxyQueueManager prxQ) 
     { 
      dnqManager = dnq; 
      ProxyManager = prxQ; 
     } 

     private DNQueueManager dnqManager; 
     private ProxyQueueManager ProxyManager; 
     public StagingQueue StagingQueue = new StagingQueue(); 
     public MetricsQueueManager MQmanager = new MetricsQueueManager(); 
     public CommitQueueManager CQmanager = new CommitQueueManager(); 


     protected void Run1() 
     { 
      dnqManager.LoadDNs(); 
      ProxyManager.LoadProxies(); 

      while (true) 
      { 
       if (dnqManager.IsDNDavailable) 
       { 
        DomainData dnd = dnqManager.GetDND(); 
        dnd.PageSource = CapturePage(dnd.DomainName); 
        StagingQueue.AddDN2Q(dnd); 
       } 
       Thread.Sleep(new Random().Next(20)); 
      } 
     } 


     protected void Run2() 
     { 
      while (true) 
      { 
       if (StagingQueue.IsDNDavailable) 
       { 
        DomainData dnd = StagingQueue.GetDND(); 

        MaxOutboundLinks = 3; 
        AvoidHttps = true; 
        InsideLinks = false; 
        VerifyBackLinks = true; 

        MQmanager.AddDN2Q(ParsePage(dnd)); 

        foreach (string link in dnd.Hlinks) 
        { 
         DomainData dndLink = new DomainData(dnd.MainSeqno,link.ToString()); 
         dndLink.ParentDomainName = dnd.DomainName; 
         dnd.PageSource = String.Empty; 
         MQmanager.AddDN2Q(dndLink); 
        }      
       } 
       Thread.Sleep(new Random().Next(20)); 
      } 
     } 


     protected void Run3() 
     { 
      while (true) 
      { 
       if (MQmanager.IsDNDavailable) 
       { 
        DomainData dnd = MQmanager.GetDND(); 
        RunAlexa(dnd); 
        RunCompete(dnd); 
        RunQuantcast(dnd); 

        CQmanager.AddDN2Q(dnd, MQmanager, 1000); 
       } 
       Thread.Sleep(new Random().Next(20)); 
      } 
     } 


     private string CapturePage(string URIstring) 
     { 
      Uri myUri; 
      try 
      { 
       myUri = new Uri(URIstring); 
      } 
      catch (Exception URIex) 
      { 
       return String.Empty; 
      } 

      string proxyIP = ProxyManager.GetCurrentProxy() == "" ? ProxyManager.GetProxy() : ProxyManager.GetCurrentProxy(); 
      int proxCtr = 0; 

      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(myUri); 
      WebProxy Proxy = new WebProxy(proxyIP); 
      request.Proxy = Proxy; 
      request.Timeout = 20000; 

      try 
      { 
       using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 
       { 
        using (StreamReader strmRdr = new StreamReader(response.GetResponseStream(), Encoding.ASCII)) 
        { 
         return strmRdr.ReadToEnd(); 
        } 
       } 
      } 
      catch (InvalidOperationException Wex) 
      { 
       . . . 
      } 
     } 

Répondre

2

Vous utilisez un StreamReader avec un codage ASCII. Si les données envoyées par le serveur n'ont pas un codage ASCII valide, StreamReader n'écrira pas les données correctement dans la chaîne.

Notez que le serveur peut mettre explicitement un encodage de page sur les en-têtes de réponse ou utiliser une balise META dans le contenu de la page lui-même.

La page suivante vous montre comment télécharger des données en utilisant les codages correctes: http://blogs.msdn.com/feroze_daud/archive/2004/03/30/104440.aspx

Il est également possible que vous ne recevez pas le corps d'entité complète du serveur, cela pourrait être dû à une mauvaise proxy, ou autre chose. Peut-être que vous voudrez peut-être ajouter plus de diagnostics dans votre application. Enregistrez les # octets téléchargés et le proxy utilisé. Ensuite, vous pouvez faire un Encoding.ASCII.GetBytes (string) .Length et assurez-vous qu'il est le même que le #bytes téléchargé. Si ce n'est pas le cas, vous avez un problème avec les encodages de page. Si ce n'est pas le cas, alors vous avez un mauvais proxy sur le chemin.

Espérons que cela aide.

+0

Merci beaucoup, feroze. J'ai appliqué vos suggestions et mon problème est résolu. Maintenant, je travaille sur des appels Web asynchrones. Toutes les suggestions de vous ou d'autres seraient géniales. BTW, j'aime ce site. J'apprends tellement en lisant la FAQ et les commentaires. Salut à tous ceux qui contribuent! – JLP188

Questions connexes