violation Protocole HTTP lorsque page Web de téléchargement en utilisant HtmlAgilityPack
-
09-10-2019 - |
Question
Je suis en train de pages de téléchargement de parse www.mediafire.com, mais je suis vraiment souvent System.Net.WebException
avec le message suivant, lorsque je tente de charger une page à un HtmlDocument
:
Le serveur a commis un protocole violation. 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)
{
}
Toutes les idées pourquoi seulement 10 des 30 liens de travail (les liens à chaque changement, parce que mon programme est un « moteur de recherche ») et comment je peux résoudre le problème?
Quand je charge ces sites dans mon navigateur, tout fonctionne bien.
J'ai essayé d'ajouter les lignes suivantes à fait mon app.config, mais qui ne l'aide soit
<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing="true" />
</settings>
</system.net>
La solution
Ce n'est pas lié au pack Html Agility directement, mais plutôt à la couche HTTP / socket sous-jacente. Cette erreur signifie que le serveur ne renvoit une ligne d'état HTTP correct.
La ligne d'état est défini dans la RFC HTTP disponible ici: http: // www .w3.org / Protocoles / RFC2616 / RFC2616-sec6.html
Je cite:
La première ligne d'un message de réponse est la ligne d'état, composé du version du protocole suivi d'un numérique code d'état et son contenu textuel associé phrase, chaque élément étant séparé par caractères SP. Aucun CR ni LF est autorisé sauf dans la séquence de CRLF finale.
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
Vous pouvez ajouter des traces de socket avec rapport complet hexagonale pour vérifier:
<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 va créer un fichier SocketTrace.log dans le répertoire exécution en cours. Jetez un coup d'oeil là-dedans, la violation du protocole doit être visible. Vous pouvez poster ici si c'est pas trop grand: -)
Malheureusement, si vous ne possédez pas le serveur, il n'y a pas grand-chose que vous pouvez faire (si vous avez déjà ajouté le paramètre useUnsafeHeaderParsing, ce qui est bon) mais ne parviennent pas gracieusement dans ces cas.
Autres conseils
Réglage garder la propriété en vie à false résoudre ce problème. Mais je ne sais pas si htmlagilitypack a cette propriété. Donc, en utilisant WebClient serait une meilleure alternative.
Cela a fonctionné pour moi. Au lieu de charger directement l'url avec web.Load, télécharger le code html d'URL souhaitée à l'aide de votre WebClient personnalisé. Dans votre méthode override GetWebRequest WebClient personnalisé pour faire HttpWebRequest.KeepAlive = false. Maintenant charger 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");
Redéfinition 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;
}
}
}