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

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

Вопрос

Я пытаюсь проанализировать страницы загрузки с сайта www.mediafire.com, но я действительно часто получаю сообщение System.Net.WebException со следующим сообщением, когда я пытаюсь загрузить страницу в HtmlDocument :

Сервер совершил нарушение протокола. Раздел = ResponseStatusLine

Это мой код:

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 ссылок (ссылки меняются каждый раз, потому что моя программа - «поисковая система») и как я могу решить проблему?

Когда я загружаю эти сайты в своем браузере, все работает нормально.


Я попытался добавить следующие строки в свой app.config, но это не помогает ни

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

Принятый ответ

Это не относится непосредственно к Html Agility Pack, а относится к основному слою 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 в текущей исполняющей директории. Обратите внимание, что нарушение протокола должно быть видимым. Вы можете опубликовать его здесь, если он не слишком большой :-)

К сожалению, если вы не владеете сервером, вы не можете сделать это (если вы уже добавили параметр useUnsafeHeaderParsing, что хорошо), но в этих случаях изящно изящно.


Популярные ответы

Установка свойства keep alive в значение false приведет к устранению этой проблемы. Но я не уверен, имеет ли htmlagilitypack это свойство. Поэтому использование WebClient было бы лучшей альтернативой.

Это сработало для меня. Вместо того, чтобы напрямую загружать URL с помощью web.Load, загрузите html нужного URL-адреса, используя свой собственный WebClient. В вашем пользовательском WebClient переопределите метод GetWebRequest, чтобы сделать HttpWebRequest.KeepAlive = false. Загрузите загруженный файл в web.Load ().

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


Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему