2009-09-04 10 views
13

escribí este método para comprobar si existe una página o no:¿Existe alguna manera más rápida de verificar si existe una página web externa?

protected bool PageExists(string url) 
{ 
try 
    { 
     Uri u = new Uri(url); 
     WebRequest w = WebRequest.Create(u); 

      w.Method = WebRequestMethods.Http.Head; 

     using (StreamReader s = new StreamReader(w.GetResponse().GetResponseStream())) 
     { 
      return (s.ReadToEnd().Length >= 0); 
     } 
    } 
     catch 
    { 
     return false; 
     } 
    } 

lo estoy usando para comprobar un conjunto de páginas (itera desde AAAA-aaaz), y se tarda entre 3 y 7 segundos para correr todo el ciclo ¿Hay una manera más rápida o más eficiente de hacer esto?

+0

¿Hay una manera de conseguir a tan sólo las cabeceras, y comprobar si hay 200? –

Respuesta

37

Creo que su enfoque es bastante bueno, pero lo cambiaría a solo descargando los encabezados agregando w.Method = WebRequestMethods.Http.Head; antes de llamar al GetResponse.

Esto podría hacerlo:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.example.com"); 
request.Method = WebRequestMethods.Http.Head; 
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
bool pageExists = response.StatusCode == HttpStatusCode.OK; 

Es posible que probablemente desee marcar para otros códigos de estado también.

+1

Exactamente. ¿Por qué leer todo el camino hasta el final cuando solo los primeros bytes de vista lo harán? –

+5

Y compruebe el estado de la respuesta. –

+0

@Viktor: buena sugerencia; Estaba escribiendo el ejemplo del código mientras lo daba: o) –

0

Una aceleración obvia es ejecutar varias solicitudes en paralelo: la mayor parte del tiempo se gastará en IO, por lo que generar 10 hilos para cada control de una página completará toda la iteración unas 10 veces más rápido.

1
static bool GetCheck(string address) 
{ 
    try 
    { 
     HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest; 
     request.Method = "GET"; 
     request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); 
     var response = request.GetResponse(); 
     return (response.Headers.Count > 0); 
    } 
    catch 
    { 
     return false; 
    } 
} 
static bool HeadCheck(string address) 
{ 
    try 
    { 
     HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest; 
     request.Method = "HEAD"; 
     request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); 
     var response = request.GetResponse(); 
     return (response.Headers.Count > 0); 
    } 
    catch 
    { 
     return false; 
    } 
} 

Cuidado, ciertas páginas (por ejemplo. .SVC archivos WCF) puede no devolver nada a partir de una solicitud de la cabeza. Lo sé porque estoy trabajando en esto ahora mismo.
EDITAR - Sé que hay mejores formas de verificar los datos de retorno que contar encabezados, pero esto es una copia/pega de cosas donde esto es importante para nosotros.

+0

Ah sí, y puedes refactorizar a un solo método que tome "GET" o "HEAD" como un param, si quieres ser todo eficiente también. ;) – ZombieSheep

0
  1. Puede hacerlo de forma asíncrona, porque ahora está esperando resultados después de cada solicitud. En algunas páginas, solo puede lanzar su función en ThreadPool y esperar a que finalicen todas las solicitudes. Para más solicitudes, puede usar métodos asincrónicos para su ResponseStream() (BeginRead, etc.).
  2. La otra cosa que puede ayudar a usted (me ayude a ciencia cierta) es despejar .Proxy propiedad:
w.Proxy = null;

Sin esto, al menos primera petición es mucho más lento, al menos en mi máquina.
3. No puede descargar toda la página, sino descargar solo el encabezado, configurando .Method en "HEAD".

-2

simplemente he usado Fredrik Mörk respuesta anterior, pero lo colocó dentro de un método:

private bool checkURL(string url) 
     { 
      bool pageExists = false; 
      try 
      { 
       HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
       request.Method = WebRequestMethods.Http.Head; 
       HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
       pageExists = response.StatusCode == HttpStatusCode.OK; 
      } 
      catch (Exception e) 
      { 
       //Do what ever you want when its no working... 
       //Response.Write(e.ToString()); 
      } 
      return pageExists; 
     } 
Cuestiones relacionadas