Ich versuche, Download-Seiten von www.mediafire.com zu analysieren, aber ich bekomme sehr oft eine System.Net.WebException
mit der folgenden Nachricht, wenn ich versuche, eine Seite in ein HtmlDocument
zu HtmlDocument
:
Der Server hat eine Protokollverletzung begangen. Abschnitt = ResponseStatusLine
Das 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 funktionieren (die Links ändern sich jedes Mal, weil mein Programm eine "Suchmaschine" ist) und wie kann ich das Problem lösen?
Wenn ich diese Websites in meinem Browser lade, funktioniert alles einwandfrei.
Ich habe versucht, die folgenden Zeilen zu meiner app.config hinzuzufügen, aber das hilft auch nicht
<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing="true" />
</settings>
</system.net>
Dies hängt nicht direkt mit dem Html Agility Pack zusammen, sondern mit der zugrunde liegenden HTTP / Socket-Schicht. Dieser Fehler bedeutet, dass der Server keine korrekte HTTP-Statuszeile zurücksendet.
Die Statuszeile ist in HTTP RFC definiert, das hier verfügbar ist: http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
Ich zitiere:
Die erste Zeile einer Antwortnachricht ist die Statuszeile, bestehend aus der Protokollversion, gefolgt von einem numerischen Statuscode und der zugehörigen Textphrase, wobei jedes Element durch SP-Zeichen getrennt ist. Außer in der endgültigen CRLF-Sequenz ist kein CR oder LF erlaubt.
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
Sie können Socket-Traces mit dem vollständigen Hex-Bericht hinzufügen, um 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>
Dadurch wird im aktuellen Ausführungsverzeichnis eine SocketTrace.log-Datei erstellt. Schau mal rein, die Protokollverletzung sollte sichtbar sein. Sie können es hier posten, wenn es nicht zu groß ist :-)
Wenn Sie den Server nicht besitzen, können Sie leider nicht viel tun (wenn Sie bereits die Einstellung useUnsafeHeaderParsing hinzugefügt haben, was gut ist), aber in diesen Fällen nicht ordnungsgemäß ausgeführt wird.
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 hat für mich funktioniert. Anstatt die URL direkt mit web.Load zu laden, lade die HTML der gewünschten URL mit deinem 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");
Überschreiben von 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;
}
}
}