2009-12-20 6 views
3

Je viens de voir un robot d'indexation en action sur mon ordinateur et il télécharge des milliers d'informations de métadonnées en seulement quelques minutes. Lorsque j'utilise WebClient pour télécharger des pages, puis les analyser localement, pourquoi est-ce que cela prend environ 40 secondes à WebClient pour télécharger une seule page Web? Existe-t-il une alternative au téléchargement de pages Web?Alternative à WebClient

remerciements

+0

40 secondes est anormalement long. Il me semble 300ms pour télécharger cette page en utilisant WebClient. Il y a autre chose qui se passe. –

+0

Vous pouvez rencontrer une limitation du site en raison de la chaîne d'en-tête de demande User-Agent que WebClient utilise par défaut. –

Répondre

6

Quelques choses à considérer:

  • Combien de pages vous le téléchargement à la fois? Les robots d'exploration ont tendance à fonctionner de manière très parallèle.
  • Par défaut, le framework .NET restreint le nombre de requêtes parallèles à un seul site. C'est généralement une bonne chose à faire - vous pouvez augmenter la limite un peu, mais idéalement cibler des sites différents en parallèle. L'élément <connectionManagement> est celui que vous devez regarder.
  • Avez-vous utilisé WireShark pour voir ce qui se passe au niveau du réseau? Si le site Web prend 40 secondes pour servir la page, il est difficile de voir à quel point l'utilisation de WebClient pourrait vous aider.
  • Pourriez-vous poster du code pour montrer exactement ce que vous faites?

Il est possible que l'utilisation d'une autre API (peut-être même juste WebRequest) va accélérer les choses, mais vous avez vraiment besoin de trouver le goulot d'étranglement actuel premier.

+2

À moins de connaître la cause de la lenteur, il est trop tôt pour dire que WebClient est problématique. –

1

Il y a deux raisons pour lesquelles vous pourriez obtenir de mauvaises performances:

  • pas l'utilisation de méthodes/threads asynchrones
  • algorithme d'analyse syntaxique HTML pauvre
  • La page que vous téléchargez avec WebClient est lent

Plus d'informations/code source seront nécessaires pour trouver une réponse définitive.

1

Il y a eu quelques messages relatifs à Webclient étant lent s'il y a une instance de proxy par défaut. MSDN Social a les mêmes détails à ce sujet. Il y a plusieurs choses à faire pour rendre cela plus rapide, y compris en utilisant des connexions asyncrones, des threads et si vous avez vraiment besoin de la performance en écrivant le code de socket vous-même. Il y a quelques bibliothèques sur le marché qui prétendent fournir des boosts au-dessus des bibliothèques de framework par défaut, elles peuvent être avantageuses si vous êtes prêt à payer un supplément pour elles. J'ai quelques programmes qui utilisent Webrequest (non webclient natif) et je vois des débits dans la gamme proche MB/s avec des ressources dans la gamme 10-20MB venant de la moitié du monde. Donc c'est certainement possible avec le framework nativement.

2

Il est presque certain qu'il existe un autre problème avec votre code qui n'est pas facilement détectable grâce aux informations que vous avez publiées. D'autre part, lors de la création d'un crawler C#, nous avons constaté que l'API WebRequest/WebClient était très lourde pour l'utilisation du processeur et, finalement, inadaptée à l'analyse. À la fin, nous avons écrit notre propre pile HTTP en utilisant les méthodes Socket.XxxxAsync qui ont réduit la charge du processeur d'environ 20 fois. Soyez averti qu'il y a une courbe d'apprentissage assez raide impliquée dans la poursuite de cette voie.

+0

C'était un goulot d'étranglement de cpu cependant? Étant donné la question et en supposant que le dev a testé avec une seule page et voit toujours le goulot d'étranglement, je dirais que c'est soit une page de chargement lent ou un délai d'attente. semble vouloir longtemps non plus. –

0

Ces paramètres peuvent vous aider si vous constatez un ralentissement pendant l'analyse.

ServicePointManager.DefaultConnectionLimit = int.MaxValue; 
ServicePointManager.MaxServicePoints = int.MaxValue; 
ServicePointManager.MaxServicePointIdleTime = 0; 

N'oubliez pas non plus de fermer HttpWebRequest si vous augmentez le niveau du code.

HttpWebResponse.Close(); 
HttpWebResponse.GetResponseStream().Close(); 
HttpWebResponse.GetResponseStream().Dispose(); 

Mike