Нарушение протокола HTTP при загрузке веб-страницы с помощью HTMLAGILYPACK

StackOverflow https://stackoverflow.com/questions/4656723

Вопрос

Я пытаюсь анализировать страницы загрузки с 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;
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top