Pregunta

Estoy tratando de páginas de descarga de análisis sintáctico de www.mediafire.com, pero realmente conseguir a menudo un System.Net.WebException con el siguiente mensaje, cuando intento cargar una página a un HtmlDocument:

El servidor comprometido un protocolo violación. Sección = ResponseStatusLine

Este es mi código:

HtmlAgilityPack.HtmlWeb web = new HtmlAgilityPack.HtmlWeb();

HtmlAgilityPack.HtmlDocument doc = null;

string url = www.mediafire.com/?abcdefghijkl //There are many different links

try
{
    doc = web.Load(url); //From 30 links, usually only 10 load properly
}

catch (WebException)
{

}

Cualquier idea por qué sólo 10 de 30 enlaces de trabajo (el cambio vínculos cada vez, porque mi programa es un "motor de búsqueda") y cómo puedo resolver el problema?

Cuando cargo esos sitios en mi navegador, todo funciona bien.


He intentado añadir las siguientes líneas a mi app.config, pero eso no ayuda tampoco

<system.net>
    <settings>
        <httpWebRequest useUnsafeHeaderParsing="true" />
    </settings>
</system.net>
¿Fue útil?

Solución

Esto no está relacionado con la agilidad Paquete HTML directamente, sino más bien a la HTTP / socket capa subyacente. Este error significa que el servidor no está enviando de vuelta una línea de estado HTTP correcto.

La línea de estado HTTP se define en el RFC disponible aquí: http: // www .w3.org / Protocolos / RFC2616 / RFC2616-sec6.html

cito:

La primera línea de un mensaje de respuesta es el estado de línea, que consiste en la versión de protocolo seguido de una numérico código de estado y su texto asociado frase, con cada elemento separado por personajes SP. No se permite la CR o LF excepto en la secuencia CRLF final.

   Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF

Se puede añadir trazas de socket con el informe completo hexagonal para comprobar esto:

<configuration>
    <system.diagnostics>
        <sources>
            <source name="System.Net.Sockets" tracemode="includehex">
                <listeners>
                    <add name="System.Net.Sockets" type="System.Diagnostics.TextWriterTraceListener" initializeData="SocketTrace.log" />
                </listeners>
            </source>
        </sources>
        <switches>
            <add name="System.Net.Sockets" value="Verbose"/>
        </switches>
        <trace autoflush="true" />
    </system.diagnostics>
</configuration>

Esto creará un archivo SocketTrace.log en el directorio de ejecución actual. Echar un vistazo ahí, la violación del protocolo debe ser visible. Puede publicar aquí si no es demasiado grande: -)

Desafortunadamente, si usted no posee el servidor, no hay mucho que puede hacer (si ya ha añadido el ajuste useUnsafeHeaderParsing, lo cual es bueno) pero fracasan con gracia en estos casos.

Otros consejos

Configuración de mantener la propiedad viva en false van a resolver ese problema. Pero no estoy seguro de si htmlagilitypack tiene esta propiedad. Así, utilizando WebClient sería una alternativa mejor.

Esto funcionó para mí. En lugar de cargar directamente la url con web.Load, descarga el código HTML de URL que desee usando el cliente Web personalizado. En el método de reemplazo GetWebRequest cliente Web personalizado para hacer HttpWebRequest.KeepAlive = false. Ahora carga el archivo descargado en web.Load ().

MyWebClient client = new MyWebClient();
client.DownloadFile(searchURL, @"C:\\index.html");
var doc = web.Load("C:\\index.html");

Anulación GetWebRequest

using System;
using System.Net;

namespace MyProject
{
    internal class CustomWebClient : WebClient
    {
        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest request = base.GetWebRequest(address);
            if (request is HttpWebRequest)
            {
                (request as HttpWebRequest).KeepAlive = false;
            }
            return request;
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top