晚上好,
我制作了一个程序来向具有某些标题等的网站发出请求,我正在检查该页面是否包含某个字符串。问题是每个网站需要大约一分钟。如果可能的话,我想要一种优化它的方法。我很确定问题是reader.ReadToEnd。我猜在我找到匹配之前我可以阅读。这是代码,非常感谢。
foreach (string s in lines)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(s);
request.ContentType = "application/x-www-form-urlencoded";
request.Host = s;
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)";
request.Method = "GET";
request.Proxy = null;
string source;
try
{
using (StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream()))
{
source = reader.ReadToEnd();
if (source.Contains("xxxxx"))
{
MessageBox.Show(s);
}
}
}
catch
{
}
}
答案 0 :(得分:0)
如果下载单个页面需要很长时间,那么您无能为力。但是,猜测使得它花费这么长时间的资源不是最终的,您可以并行请求所有这些站点。这样,如果一个人需要3秒钟,运气不错,所有将需要3秒钟。
首先,您需要将下载放入自己的方法中:
private static bool SiteContains(string url, string searchText)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(s);
request.ContentType = "application/x-www-form-urlencoded";
request.Host = s;
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13 (.NET CLR 3.5.30729)";
request.Method = "GET";
request.Proxy = null;
using (StreamReader reader = new StreamReader(request.GetResponse().GetResponseStream()))
{
var source = reader.ReadToEnd();
return source.Contains(searchText);
}
}
请注意,我跳过了示例的错误处理,您需要添加一些。
然后您可以使用PLinQ并行处理您的列表:
var results = lines.AsParallel().Select( line => new { Site = line, Result = SiteContains(line, "xxxxx") } );
foreach(var result in results)
{
Console.WriteLine("Site={0}, Result={1}", result.Site, result.Result);
}
执行下载和检查将并行进行,最后的foreach循环仅用于事后输出。您可能希望将其替换为类似于列表框或消息框的Windows窗体解决方案。
答案 1 :(得分:0)
首先,不要试图刮刮谷歌,否则你将陷入痛苦的世界。 特别是不要像我们所建议的那样刮掉Google并将请求并行化。尽可能快地击中他们或任何有尽可能多的请求的人,是一种可靠的方法。
其次,我假设您正在寻找比xxxxxxx更复杂的东西。如果您需要进行任何解析,请尝试NuGet中的HTMLAgilityPack。
第三,如果你想简化这一点,让一个线程进行下载到本地位置,然后在第二个线程中处理文件队列进行搜索。这在测试期间尤其有用,您可能会反复重新运行此代码,直到您做对了。