Violation du protocole HTTP lors du téléchargement d'une page Web à l'aide de HtmlAgilityPack

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

Question

J'essaie d'analyser les pages de téléchargement à partir de www.mediafire.com, mais je reçois souvent une System.Net.WebException avec le message suivant, lorsque j'essaie de charger une page dans un document HtmlDocument :

Le serveur a commis une violation de protocole. Section = ResponseStatusLine

Ceci est mon 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)
{

}

Des idées pour lesquelles seulement 10 des 30 liens fonctionnent (les liens changent à chaque fois, car mon programme est un "moteur de recherche") et comment puis-je résoudre le problème?

Lorsque je charge ces sites dans mon navigateur, tout fonctionne correctement.


J'ai essayé d'ajouter les lignes suivantes à mon app.config, mais cela n'aide pas non plus.

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

Réponse acceptée

Cela n’est pas directement lié au pack d’agilité HTML, mais à la couche HTTP / socket sous-jacente. Cette erreur signifie que le serveur n'envoie pas une ligne d'état HTTP correcte.

La ligne d'état est définie dans HTTP RFC disponible à l' adresse suivante : http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html

Je cite:

La première ligne d'un message de réponse est la ligne d'état, composée de la version du protocole suivie d'un code d'état numérique et de la phrase textuelle associée, chaque élément étant séparé par un caractère SP. Aucun CR ou LF n'est autorisé sauf dans la séquence finale du CRLF.

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

Vous pouvez ajouter des traces de socket avec un rapport hexadécimal complet pour vérifier ceci:

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

Cela créera un fichier SocketTrace.log dans le répertoire en cours d'exécution. Regardez là-dedans, la violation de protocole devrait être visible. Vous pouvez le poster ici s'il n'est pas trop gros :-)

Malheureusement, si vous ne possédez pas le serveur, vous ne pouvez pas faire grand chose (si vous avez déjà ajouté le paramètre useUnsafeHeaderParsing, ce qui est bien), mais vous échouerez normalement.


Réponse populaire

Définir la propriété keep alive sur false résoudra ce problème. Mais je ne suis pas sûr si htmlagilitypack a cette propriété. Donc, utiliser WebClient serait une meilleure alternative.

Cela a fonctionné pour moi. Au lieu de charger directement l'URL avec web.Load, téléchargez le code HTML de l'URL souhaitée à l'aide de votre client Web personnalisé. Dans votre méthode WebClient personnalisée, remplacez la méthode GetWebRequest par HttpWebRequest.KeepAlive = false Maintenant, chargez le fichier téléchargé dans web.Load ().

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

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


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi