我正在尝试从www.mediafire.com解析下载页面,但是当我尝试将页面加载到System.Net.WebException
时,我经常会收到HtmlDocument
以及以下消息: / p>
服务器提交了协议 违反。节= 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)
{
}
任何想法为什么只有30个链接中的10个可以使用(链接每次都会更改,因为我的程序是“搜索引擎”)以及我如何解决问题?
当我在浏览器中加载这些网站时,一切正常。
我尝试将以下行添加到我的app.config中,但这对
无效<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing="true" />
</settings>
</system.net>
答案 0 :(得分:3)
这与Html Agility Pack没有直接关系,而是与底层HTTP /套接字层有关。此错误表示服务器未发送回正确的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设置,这很好)但在这些情况下优雅地失败。
答案 1 :(得分: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;
}
}
}