2011-01-11 113 views
2

我試圖從www.mediafire.com解析下載頁面,但當我嘗試將頁面加載到HtmlDocument時,我確實經常收到帶有以下消息的System.Net.WebException使用HtmlAgilityPack下載網頁時違反HTTP協議

服務器承諾協議 違規。第= 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> 
+0

。你可以嘗試使用`WebRequest`並構造一個類似於你的瀏覽器的請求。 – alexn 2011-01-11 11:48:28

+0

你可以提供一些關於這樣做的更多信息嗎?也許鏈接到一個教程或什麼的? – Flagbug 2011-01-11 12:04:11

回答

3

這是沒有直接關係的HTML敏捷性包,而是底層的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 

可以全六角報表添加插座的痕跡進行檢查:

<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設置,這是好的),但失敗在這些情況下優雅。

+0

唯一可以做的事情是聯繫服務器負責人並告知他們問題。根據他們他們可能會決定解決這個問題,但像西蒙說,你無法控制服務器,他們不需要修復它 – RobV 2011-01-11 13:14:19

0

將keep alive屬性設置爲false將解決此問題。但我不確定htmlagilitypack是否有此屬性。所以使用WebClient會是一個更好的選擇。

這對我有效。 不要直接使用web.Load加載url,請使用您的自定義WebClient下載所需url的html。在您的自定義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; 
     } 
    } 
} 
相關問題