Нарушение протокола HTTP при загрузке веб-страницы с помощью HTMLAGILYPACK
-
09-10-2019 - |
Вопрос
Я пытаюсь анализировать страницы загрузки с www.mediafire.com, но я действительно часто получаю System.Net.WebException
со следующим сообщением, когда я пытаюсь загрузить страницу на HtmlDocument
:
Сервер совершил нарушение протокола. Раздел = ОтветкаTUSLINE.
Это мой код:
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)
{
}
Любые идеи, почему только 10 из 30 ссылок работает (ссылки меняются каждый раз, потому что моя программа - «поисковая система») и как я могу решить проблему?
Когда я загружу эти сайты в моем браузере, все работает нормально.
Я пытался добавить следующие строки в мое приложение.config, но это тоже не помогает
<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing="true" />
</settings>
</system.net>
Решение
Это не связано с пакетом ловкости HTML напрямую, а скорее к основному слою HTTP / Socket. Эта ошибка означает, что сервер не отправляет правильную строку состояния HTTP.
Строка состояния определяется в HTTP RFC здесь: http://www.w3.org/protocols/rfc2616/rfc2616-sec6.html.
Я цитирую:
Первая строка ответного сообщения - это строка состояния, состоящая из версии протокола, за которой следует цифровой код состояния, а также связанная текстовая фраза, с каждым элементом, разделенными символами SP. Нет CR или LF не допускается, кроме как в конечной последовательности CRLF.
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
Вы можете добавить следы сокетов с полным отчетом о шестигранниках, чтобы проверить это:
<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>
Это создаст файл SocketTrace.log в текущем каталоге выполнения. Посмотрите там, нарушение протокола должно быть видно. Вы можете опубликовать это здесь, если он не слишком большой :-)
К сожалению, если у вас нет сервера, не так много, что вы уже можете сделать (если вы уже добавили настройку apsunsafeheaderParsing, которая хорошая), но изящно изящна в этих случаях.
Другие советы
Настройка сохраняют живое свойство для false исправит эту проблему. Но я не уверен, есть ли HTMLAGILYPACK, имеет это свойство. Поэтому, используя WebClient, будет лучшая альтернатива.
Это сработало для меня. Вместо непосредственно загрузки URL с помощью Web.Bload загрузите HTML нужного URL-адреса, используя свой пользовательский WebClient. В вашем пользовательском WebClient переопределите метод GetWrequest, чтобы сделать httpwebrequest.seeparive = false. Теперь загрузите загруженный файл в Web.bload ().
MyWebClient client = new MyWebClient();
client.DownloadFile(searchURL, @"C:\\index.html");
var doc = web.Load("C:\\index.html");
Переопределение 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;
}
}
}