2011-01-11 5 views
2

Ich versuche, Download-Seiten von www.mediafire.com zu analysieren, aber mir wirklich oft ein System.Net.WebException mit der folgenden Meldung erhalten, wenn ich versuche, eine Seite zu einem HtmlDocument zu laden:HTTP-Protokoll Verletzung, wenn die Homepage HtmlAgilityPack mit dem Download

Der Server hat ein Protokoll Verletzung begangen. Section = ResponseStatusLine

Dies ist mein Code:

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

} 

Irgendwelche Ideen, warum nur 10 von 30 Links Arbeit (die Links jedes Mal ändern, weil mein Programm eine "Suchmaschine" ist) und wie kann ich das Problem lösen?

Wenn ich diese Seiten in meinem Browser lade, funktioniert alles gut.


Ich habe versucht, die folgenden Zeilen zu meinem app.config hinzufügen, aber das hilft auch nicht

<system.net> 
    <settings> 
     <httpWebRequest useUnsafeHeaderParsing="true" /> 
    </settings> 
</system.net> 
+0

Sie sind wahrscheinlich zur Erkennung nicht-Webbrowsern Sniffing User-Agent/Cookie/Header verwendet wird. Sie könnten versuchen, eine 'WebRequest' zu verwenden und eine Anfrage ähnlich Ihren Browsern zu erstellen. – alexn

+0

Kannst du mir vielleicht mehr Informationen darüber geben? Vielleicht ein Link zu einem Tutorial oder etwas? – Flagbug

Antwort

3

Dies ist nicht auf die Html Agility Pack einfach direkt, bezogen, sondern auf die zugrunde liegende HTTP/Socket-Schicht. Dieser Fehler bedeutet, dass der Server keine korrekte HTTP-Statuszeile zurücksendet.

Die Statuszeile in HTTP RFC hier definiert ist: http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html

Ich zitiere:

Die erste Zeile einer Antwortnachricht ist die Status-Zeile, von der Version Protokoll bestehend gefolgt durch einen numerischen Statuscode und die zugehörige textuelle Phrase, wobei jedes Element durch SP Zeichen getrennt ist. Kein CR oder LF ist zulässig außer in der endgültigen CRLF-Sequenz.

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

Sie können Socket-Spuren mit voller Hex-Bericht hinzufügen, dies zu überprüfen:

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

Dies wird eine SocketTrace.log Datei im aktuellen Ausführung Verzeichnis erstellen. Schau mal rein, die Protokollverletzung sollte sichtbar sein. Sie können es hier posten, wenn es nicht zu groß ist :-)

Leider, wenn Sie nicht den Server besitzen, gibt es nicht viel, was Sie tun können (wenn Sie bereits die useUnsafeHeaderParsing Einstellung hinzugefügt, die gut ist) aber scheitern anmutig in diesen Fällen.

+0

Sie können nur die Verantwortlichen des Servers kontaktieren und sie über das Problem informieren. Abhängig von ihnen können sie entscheiden, das Problem zu beheben, aber wie Simon sagt, Sie haben keine Kontrolle über den Server und sie müssen es nicht beheben – RobV

0

Wenn Sie die Eigenschaft keep alive auf false setzen, wird dieses Problem behoben. Aber ich bin mir nicht sicher, ob htmlagilitypack diese Eigenschaft hat. Daher wäre die Verwendung von WebClient eine bessere Alternative.

Das funktionierte für mich. Anstatt die URL direkt mit web.Load zu laden, laden Sie die HTML der gewünschten URL mit Ihrem benutzerdefinierten WebClient herunter. Überschreiben Sie in Ihrem benutzerdefinierten WebClient die Methode GetWebRequest, um HttpWebRequest.KeepAlive = false zu setzen. Laden Sie nun die heruntergeladene Datei in web.Load().

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

GetWebRequest Aufschalten

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; 
     } 
    } 
} 
+0

Schlägst du vor, dass der Server, mit dem er arbeitet, Probleme mit KeepAlive-Anfragen oder einfach das hat Direktes Verwenden von WebClient hätte das Problem vermieden. Du hast nie wirklich gesagt, was du glaubst, was sein Problem ist. –

+0

Ja, das Problem ist eine Antwort vom Server. Wenn Sie "Keep" auf "False" setzen, wird dieses Problem behoben. Aber ich bin mir nicht sicher, ob htmlagilitypack Eigentum am Leben erhalten hat. Daher wäre die Verwendung von WebClient eine bessere Alternative. Vielen Dank! – Shami