我正在尝试在C#中实现有限的网络抓取工具(仅限几百个网站) 使用HttpWebResponse.GetResponse()和Streamreader.ReadToEnd(),也尝试使用StreamReader.Read()和循环来构建我的HTML字符串。
我只下载大约5-10K的页面。
一切都很慢!例如,平均GetResponse()时间约为半秒,而平均StreamREader.ReadToEnd()时间约为5秒!
所有网站都应该非常快,因为它们非常靠近我的位置,并且拥有快速的服务器。 (在资源管理器中对D / L几乎没有任何意义)我没有使用任何代理。
我的Crawler有大约20个线程同时从同一个站点读取。这会导致问题吗?
如何减少StreamReader.ReadToEnd DRASTICALLY?
答案 0 :(得分:15)
HttpWebRequest可能需要一段时间来检测您的proxy settings。尝试将此添加到您的应用程序配置:
<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();
}
}
答案 1 :(得分:8)
WebClient的DownloadString是HttpWebRequest的一个简单包装器,您可以尝试暂时使用它并查看速度是否提高?如果事情变得更快,你可以分享你的代码,这样我们可以看看它可能有什么问题吗?
修改强>
似乎HttpWebRequest遵守IE的“最大并发连接数”设置,这些网址是否在同一个域中?您可以尝试增加连接限制,看看是否有帮助?我找到了关于这个问题的this article:
默认情况下,您无法执行更多操作 超过2-3异步HttpWebRequest(取决于 在操作系统上)。为了覆盖它 (最简单的方法,恕我直言)不要忘记 添加这个 应用程序配置中的部分 文件:
<system.net>
<connectionManagement>
<add address="*" maxconnection="65000" />
</connectionManagement>
</system.net>
答案 2 :(得分:4)
我遇到了同样的问题,但当我将HttpWebRequest的Proxy参数设置为null时,它解决了这个问题。
UriBuilder ub = new UriBuilder(url);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( ub.Uri );
request.Proxy = null;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
答案 3 :(得分:1)
您是否尝试过ServicePointManager.maxConnections?对于类似的事情,我通常将其设置为200。
答案 4 :(得分:1)
我遇到了同样的问题,但最糟糕的是。 response =(HttpWebResponse)webRequest.GetResponse();在我的代码中 在运行更多代码之前延迟了大约10秒,之后下载使我的连接无法使用。
kurt的回答defaultProxy enabled =“false”
解决了这个问题。现在响应几乎是即时的,我可以在我的连接最高速度下载任何http文件:) 抱歉英文不好
答案 5 :(得分: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);
}
答案 6 :(得分: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;
}
答案 7 :(得分:0)
为什么多线程不能解决这个问题?多线程将最小化网络等待时间,并且由于您将缓冲区的内容存储在系统内存(RAM)中,因此处理文件系统不会出现IO瓶颈。因此,您的82页下载和解析时间为82秒,应该花费15秒(假设处理器为4倍)。如果我错过了什么,请纠正我。
____下载线_____ *
下载内容
表单流
阅读内容
_________________________ *
答案 8 :(得分:0)
尝试像这样向您的请求添加cookie(AspxAutoDetectCookieSupport=1
)
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(new Cookie("AspxAutoDetectCookieSupport", "1") { Domain = target.Host });