我有一个Windows桌面应用程序,用于使用Web浏览器在网站上进行Web Scraping。
我不得不使用WebBrowser,因为该网站实现了一些Javascript功能,因此这是获取页面的html内容的唯一方法。
该程序必须解析大约1500页,所以我已经实现了任务延迟,以避免服务器过载(并可能被禁止)。
问题是在50-100个解析的页面之后,我得到一个内存不足错误并且程序被关闭。
这是代码:
private async void buttonProd_Click(object sender, EventArgs e)
{
const string C_Prod_UrlTemplate = "http://www.mysite.it";
var _searches = new List<Get_SiteSearchResult>();
using (ProdDataContext db = new ProdDataContext())
{
_searches = db.Get_SiteSearch("PROD").ToList();
foreach (var s in _searches)
{
WebBrowser wb1 = new WebBrowser();
wb1.ScriptErrorsSuppressed = true;
Uri uri = new Uri(String.Format(C_Prod_UrlTemplate,s.prod));
wb1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
wb1.Url = uri;
await Task.Delay(90 * 1000);
}
}
}
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
using (ProdDataContext db = new ProdDataContext())
{
WebBrowser wb = (WebBrowser)sender;
string s = wb.Document.Body.InnerHtml;
string fName = wb.CodSite + "_" + wb.PostId + ".txt";
File.WriteAllText(wb.FolderPath + @"LINKS\" + fName, s);
db.Set_LinkDownloaded(wb.CodSite, wb.PostId);
}
}
在webBrowser DocumentCompleted方法中的此命令行上生成错误消息:
string s = wb.Document.Body.InnerHtml;
感谢支持
您可以简单地获取与URL相关联的字符串(仅限HTML代码),而不是使用控件(这是一个相当复杂的构造,需要比简单对象更多的内存):
using(WebClient wc = new WebClient()) {
string s = wc.DownloadString(url);
// do stuff with content
}
当然,您应该确保一些错误处理(甚至可能是重试机制)并设置一些延迟,以确保您不会在每个时间间隔内执行太多请求。