質問

www.mediafire.comからダウンロードページを解析しようとしていますが、本当に頻繁に取得します System.Net.WebException 次のメッセージで、ページをにロードしようとするとき HtmlDocument:

サーバーはプロトコル違反をコミットしました。セクション= restonseStatusline

これは私のコードです:

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

}

なぜ30のリンクのうち10個のみが機能するのか(私のプログラムが「検索エンジン」であるため、リンクが毎回変更される)と、問題を解決する方法は?

ブラウザにそれらのサイトをロードすると、すべてが正常に機能します。


次の行をapp.configに追加しようとしましたが、それも役に立ちません

<system.net>
    <settings>
        <httpWebRequest useUnsafeHeaderParsing="true" />
    </settings>
</system.net>
役に立ちましたか?

解決

これは、HTML Agility Packに直接関係していませんが、基礎となるHTTP/ソケットレイヤーに関連しています。このエラーは、サーバーが正しいHTTPステータスラインを返送していないことを意味します。

ステータス行は、ここで入手可能なHTTP RFCで定義されています。 http://www.w3.org/protocols/rfc2616/rfc2616-sec6.html

私は引用します:

応答メッセージの最初の行はステータスラインで、プロトコルバージョンとそれに続く数値ステータスコードとそれに関連するテキストフレーズで構成され、各要素はSP文字で分離されています。最終的なCRLFシーケンスを除いて、CRまたはLFは許可されていません。

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

これを確認するために、完全な16進レポート付きのソケットトレースを追加できます。

<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の設定を追加した場合、これは良いことです)が、これらの場合には優雅に失敗します。

他のヒント

Alive PropertyをFalseに設定すると、この問題が修正されます。しかし、htmlagilitypackがこのプロパティを持っているかどうかはわかりません。したがって、WebClientを使用することはより良い選択肢です。

これは私のために働いた。 URLをWeb.Loadで直接ロードする代わりに、カスタムWebClientを使用して目的のURLのHTMLをダウンロードします。 httpwebrequest.keepalive = falseを作成するカスタムWebClient Override getWebRequestメソッド。次に、ダウンロードしたファイルを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;
        }
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top