HTTP-Protokollverletzung beim Herunterladen von Webseiten mit HtmlAgilityPack

.net c# html-agility-pack system.net.webexception

Frage

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>

Akzeptierte Antwort

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.


Beliebte Antwort

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


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum