Domanda

Sto cercando di pagine di download di parsing da www.mediafire.com, ma io in realtà spesso ottenere un System.Net.WebException con il seguente messaggio, quando provo a caricare una pagina ad un HtmlDocument:

  

Il server ha commesso un protocollo   violazione. Sezione = ResponseStatusLine

Questo è il mio codice:

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)
{

}

Tutte le idee perché solo 10 dei 30 collegamenti di lavoro (il link cambio ogni volta, perché il mio programma è un "motore di ricerca") e come posso risolvere il problema?

Quando carico quei siti nel mio browser, tutto funziona bene.


ho cercato di aggiungere le seguenti righe al mio app.config, ma che non aiuta né

<system.net>
    <settings>
        <httpWebRequest useUnsafeHeaderParsing="true" />
    </settings>
</system.net>
È stato utile?

Soluzione

Questo non è correlato al HTML Agility pacchetto direttamente, ma piuttosto al HTTP / socket layer sottostante. Questo errore significa che il server non invia indietro una corretta linea di stato HTTP.

La linea di stato è definito nella RFC HTTP disponibile qui: http: // www .w3.org / protocolli / RFC2616 / RFC2616-sec6.html

cito:

  

La prima riga di un messaggio di risposta   è lo stato-Line, costituito dalla   versione del protocollo seguito da un numerico   codice di stato e il suo testo associato   frase, con ciascun elemento separato mediante   caratteri SP. Nessun CR o LF è consentito   tranne nella sequenza CRLF finale.

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

È possibile aggiungere le tracce di socket con rapporto completo esagonale per controllare questo:

<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>

Questo creerà un file nella directory SocketTrace.log esecuzione corrente. Date un'occhiata in là, la violazione del protocollo deve essere visibile. Potete postare qui se non è troppo grande: -)

Purtroppo, se non si possiede il server, non c'è molto che si può fare (se già aggiunto l'impostazione useUnsafeHeaderParsing, che è buono) ma non riescono con grazia in questi casi.

Altri suggerimenti

Impostazione mantenere la proprietà vivo su false risolverà questo problema. Ma io non sono sicuro se HtmlAgilityPack ha questa proprietà. Quindi, utilizzando WebClient sarebbe un'alternativa migliore.

Questo ha funzionato per me. Invece di caricare direttamente l'url con web.Load, scaricare il codice HTML di URL desiderato utilizzando il WebClient personalizzato. Nella tua WebClient personalizzato metodo di sostituzione GetWebRequest per rendere HttpWebRequest.KeepAlive = false. Ora caricare il file scaricato in web.Load ().

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

Overriding 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;
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top