2

我正在尝试从 www.mediafire.com 解析下载页面,但是System.Net.WebException当我尝试将页面加载到 a 时,我确实经常收到以下消息HtmlDocument

服务器违反了协议。Section=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>
4

2 回答 2

3

这与 Html Agility Pack 没有直接关系,而是与底层 HTTP/socket 层有关。此错误表示服务器未发回正确的 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 设置,这很好)但在这些情况下会正常失败。

于 2011-01-11T13:07:57.433 回答
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;
        }
    }
}
于 2016-06-10T21:25:43.423 回答