2011-01-11 103 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; 
     } 
    } 
} 
相关问题