21

我正在尝试使用 HttpWebResponse.GetResponse() 和 Streamreader.ReadToEnd() 在 C# 中实现一个有限的网络爬虫(仅适用于几百个站点),还尝试使用 StreamReader.Read() 和一个循环来构建我的 HTML 字符串。

我只下载大约 5-10K 的页面。

这一切都非常缓慢!例如,平均 GetResponse() 时间约为半秒,而平均 StreamREader.ReadToEnd() 时间约为 5 秒!

所有站点都应该非常快,因为它们离我的位置非常近,并且拥有快速的服务器。(在 Explorer 中几乎不需要 D/L)而且我没有使用任何代理。

My Crawler 有大约 20 个线程同时从同一站点读取。这会导致问题吗?

如何大幅减少 StreamReader.ReadToEnd 时间?

4

9 回答 9

16

HttpWebRequest 可能需要一段时间来检测您的代理设置。尝试将此添加到您的应用程序配置中:

<system.net>
  <defaultProxy enabled="false">
    <proxy/>
    <bypasslist/>
    <module/>
  </defaultProxy>
</system.net>

您还可能会看到缓冲读取以减少对底层操作系统套接字的调用次数会带来轻微的性能提升:

using (BufferedStream buffer = new BufferedStream(stream))
{
  using (StreamReader reader = new StreamReader(buffer))
  {
    pageContent = reader.ReadToEnd();
  }
}
于 2009-12-23T04:30:29.177 回答
8

WebClient 的 DownloadString 是 HttpWebRequest 的一个简单包装器,您可以暂时尝试使用它,看看速度是否有所提高?如果事情变得更快,您能否分享您的代码,以便我们看看它可能有什么问题?

编辑:

似乎 HttpWebRequest 观察到 IE 的“最大并发连接数”设置,这些 URL 是否在同一个域中?您可以尝试增加连接限制,看看是否有帮助?我发现这篇关于这个问题的文章:

默认情况下,您不能执行超过 2-3 个异步 HttpWebRequest(取决于操作系统)。为了覆盖它(最简单的方法,恕我直言)不要忘记在应用程序的配置文件的部分下添加它:

<system.net>
  <connectionManagement>
     <add address="*" maxconnection="65000" />
  </connectionManagement>
</system.net>
于 2009-05-23T11:31:37.593 回答
4

我有同样的问题,但是当我将 HttpWebRequest 的 Proxy 参数设置为 null 时,它解决了问题。

UriBuilder ub = new UriBuilder(url);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( ub.Uri );
request.Proxy = null;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
于 2010-09-23T12:35:09.237 回答
1

您是否尝试过 ServicePointManager.maxConnections?对于与此类似的事情,我通常将其设置为 200。

于 2010-02-14T02:03:29.043 回答
1

我遇到了同样的问题,但最糟糕的是。响应 = (HttpWebResponse)webRequest.GetResponse(); 在我的代码中延迟了大约 10 秒,然后再运行更多代码,之后下载使我的连接饱和。

库尔特的回答 defaultProxy enabled="false"

解决了这个问题。现在响应几乎是即时的,我可以以我的连接最大速度下载任何 http 文件 :) 抱歉英语不好

于 2010-02-21T15:19:34.127 回答
1

我发现Application Config方法不起作用,但问题仍然是由于代理设置造成的。我的简单请求过去最多需要 30 秒,现在需要 1 秒。

public string GetWebData()
{
            string DestAddr = "http://mydestination.com";
            System.Net.WebClient myWebClient = new System.Net.WebClient();
            WebProxy myProxy = new WebProxy();
            myProxy.IsBypassed(new Uri(DestAddr));
            myWebClient.Proxy = myProxy;
            return myWebClient.DownloadString(DestAddr);
}
于 2010-06-24T13:37:36.667 回答
0

谢谢大家的回答,他们帮助我找到了正确的方向。我遇到了同样的性能问题,尽管更改应用程序配置文件的建议解决方案(据我所知,该解决方案适用于 Web 应用程序)不符合我的需求,我的解决方案如下所示:

HttpWebRequest webRequest;

webRequest = (HttpWebRequest)System.Net.WebRequest.Create(fullUrl);
webRequest.Method = WebRequestMethods.Http.Post;

if (useDefaultProxy)
{
    webRequest.Proxy = System.Net.WebRequest.DefaultWebProxy;
    webRequest.Credentials = CredentialCache.DefaultCredentials;
}
else
{
    System.Net.WebRequest.DefaultWebProxy = null;
    webRequest.Proxy = System.Net.WebRequest.DefaultWebProxy;
}
于 2012-02-08T18:10:47.080 回答
0

为什么多线程不能解决这个问题?多线程将最大程度地减少网络等待时间,并且由于您将缓冲区的内容存储在系统内存 (RAM) 中,因此处理文件系统不会出现 IO 瓶颈。因此,需要 82 秒下载和解析的 82 个页面应该需要 15 秒(假设是 4x 处理器)。如果我遗漏了什么,请纠正我。

____ 下载主题_____*

下载内容

表单流

阅读内容

_________________________*

于 2014-12-31T01:46:52.837 回答
0

尝试AspxAutoDetectCookieSupport=1像这样将 cookie() 添加到您的请求中

request.CookieContainer = new CookieContainer();         
request.CookieContainer.Add(new Cookie("AspxAutoDetectCookieSupport", "1") { Domain = target.Host });
于 2020-11-19T10:48:17.510 回答