我正在尝试从www.mediafire.com分析页面,但我真的经常得到一个 System.Net.WebException 在以下消息中,当我尝试将页面加载到一个 HtmlDocument:

服务器违反了协议。部分= 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>
有帮助吗?

解决方案

这与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设置,那很好),但在这些情况下会优雅地失败。

其他提示

将“活着的属性”设置为false将解决此问题。但是我不确定htmlagilitypack是否具有此属性。因此,使用WebClient将是更好的选择。

这对我有用。而不是使用Web.load直接加载URL,而是使用自定义WebClient下载所需URL的HTML。在您的自定义WebClient override 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;
        }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top