2011-03-18 14 views
7

Recientemente descubrí que lo siguiente no funciona con ciertos sitios, como IMDB.com.WebRequest "HEAD" alternativa ligera

class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       System.Net.WebRequest wc = System.Net.WebRequest.Create("http://www.imdb.com"); //args[0]); 

       ((HttpWebRequest)wc).UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.2.153.1 Safari/525.19"; 
       wc.Timeout = 1000; 
       wc.Method = "HEAD"; 
       WebResponse res = wc.GetResponse(); 
       var streamReader = new System.IO.StreamReader(res.GetResponseStream()); 

       Console.WriteLine(streamReader.ReadToEnd()); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
      } 
     } 
    } 

Devuelve un HTTP 405 (método no permitido). Mi problema es que utilizo un código muy similar al anterior para verificar si un enlace es válido y la gran mayoría de las veces funciona correctamente. Puedo cambiar al método GET igual y funciona (con un aumento en el tiempo de espera), pero esto ralentiza las cosas en un orden de magnitud. Estoy asumiendo que la respuesta 405 es una configuración de servidor en el servidor de IMDB.

¿Hay alguna manera de que haga lo mismo que arriba, de una manera ligera en .NET? ¿O hay una forma de corregir el código anterior para que funcione como una solicitud GET que funciona con imdb?

+1

Tuve que aumentar el tiempo de espera, pero el código que publicaste arriba funciona para mí. Cambiarlo a POST no tendría sentido, porque no tiene ningún dato para publicar. Y su título habla sobre HEAD, pero no está haciendo una solicitud HEAD. Por favor, aclare cuál es la pregunta, ya que su código "roto" funciona bien. –

+0

Ug, error realmente estúpido en el título. Reparado ahora ... ejemplo clásico de pensar una cosa y escribir otra. Cuando ejecuta el código anterior, ¿no está obteniendo una respuesta 405? EDITAR: Ok, me di cuenta de que incluso mi código era defectuoso. Lo anterior es lo que quise publicar, y está editado para dar el error 405 (y tiene sentido ...) – Serapth

Respuesta

3

Tendrá que aclarar lo que quiere decir con "peso ligero". ¿Qué está tratando de lograr?

Si usted puede usar GET/POST/HEAD/DELETE/etc dependerá de la URL y de lo que esté configurado en la aplicación que se ejecuta en el servidor en esa URL.

Si todo lo que intenta hacer es ver si puede hacer una conexión sin descargar realmente el contenido, podría intentar simplemente iniciar una conexión al puerto 80 usando sockets, pero no hay una manera confiable o universalmente compatible simplemente cambiando el método HTTP.

+0

Bueno, en esencia, lo que estoy usando la solicitud HEAD por ahora son a) para comprobar si un sitio realmente existe b) si existe un sitio, para cada enlace dentro, verifique que realmente existe (por lo tanto, cada imagen, hoja de estilo, etc.). Por lo tanto, en algunas páginas pesadas de imágenes, literalmente podría llamarse cientos de veces. Entonces, por peso liviano me refiero principalmente al tráfico de red. – Serapth

+1

Derecha ...el único método más liviano que podría pensar en cuanto al ancho de banda sería usar sockets para construir manualmente tus solicitudes HTTP, recuperar la respuesta suficiente para determinar el código de estado HTTP y luego cerrar la conexión. –

+0

¿Seguiría la ruta del HTTP creado a mano eludir los resultados de error 405? EDITAR: Er, resultados de estado que debería haber dicho, supongo que técnicamente HTTP 405 no es en realidad un error. Solo hay un puñado de sitios que devuelven 405, y realmente no sé qué parte está causando esa respuesta. En este momento, estoy asumiendo que es la solicitud HEAD, pero no estoy seguro. – Serapth

6

Abra la conexión usted mismo con un socket (en lugar de HttpRequest o HttpRequest o WebClient), y cierre la transmisión tan pronto como haya leído el código de estado. Afortunadamente el código de estado viene cerca de la parte superior de la secuencia de respuesta :)

4

Si HEAD devuelve un 405, eso significa que el servidor no es compatible con HEAD (al menos para esa URL) y tendrá recurrir a GET en su lugar . La mayoría de los sitios deberían ser compatibles con HEAD, por lo que probablemente prefiera HEAD por defecto, pero si arroja un 405, podría volver a GET para ese dominio. O tal vez quieras probar HEAD primero para cada solicitud; YMMV.

Si el servidor requiere GET y desea reducir el tráfico de red, puede intentar hacer un GET condicional y/o un GET parcial (consulte, por ejemplo, RFC2616). Nunca he intentado hacer eso con WebRequest, pero creo que le permite agregar encabezados HTTP salientes personalizados, por lo que debería poder hacerlo.

Además, no olvide que, si está escribiendo una araña (que claramente lo es), debe respetar el archivo robots.txt del servidor, y también es cortés limitar sus solicitudes a algo así como una solicitud cada dos segundos, para que no corte el servidor.

+0

Gracias por la respuesta. En realidad, no estoy escribiendo una araña, el producto final es más parecido en naturaleza a un navegador web que cualquier otra cosa. Hice lo que sugirió anteriormente (solicitud HEAD, luego en 405 un GET completo), que es mi forma actual de hacer las cosas pero no es óptima. Analizaré los GET parciales, que probablemente sean perfectos. Gracias. – Serapth

Cuestiones relacionadas