代码改变世界

WebBrowser爬虫,用IHTMLWindow2执行js脚本

2010-11-25 16:16  watsonchia  阅读(2298)  评论(0编辑  收藏  举报

项目里需要某类代码数据,客户没有提供,让我们自己找,于是只好写爬虫上网抓数据。

目标网站的分页栏没有写成链接,而是用js提交取得分页数据,没有办法直接遍历网址。想到最容易的办法是用WebBrowser控件模拟访问页面,取得当页数据后执行js分页提交。不过执行js需要引用Microsoft.mshtml.dll,右击项目->引用->在.NET标签下找到Microsoft.mshtml,引用即可。代码里引用的命名空间为:

using mshtml;

其他的工作就容易了,WebBrowser访问页面,取得Document,用GetElementById之类的方法访问dom解析就行了,复杂点的页面可以用正则表达式。承蒙这个网站访问速度不错,9k多条数据用了十几分钟就爬完了保存到数据库,这里我用Entity Framework保存数据。总的代码并不多:

        private static int count = 1; //记录访问的页码
        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (webBrowser1.ReadyState < WebBrowserReadyState.Complete) 
                return; //保证每个页面只执行以下代码一次

            HtmlElement mainTable = webBrowser1.Document.GetElementById("ASTYLE_TB"); //跟js访问dom一样
            HtmlElementCollection trs = mainTable.GetElementsByTagName("tr");
            HtmlElementCollection tds = null;

            HtmlElement el = null;
            IMDG model = null;
            for (int i = 1; i < trs.Count; i++)
            {
                el = trs[i];
                tds = el.GetElementsByTagName("td");

                //给数据表实体赋值
            }
            context.SaveChanges(); //保存到数据库

            IHTMLDocument2 doc = webBrowser1.Document.DomDocument as IHTMLDocument2;
            IHTMLWindow2 win = doc.parentWindow;

            if (count == 481) //抓完总页数就停止
            {
                MessageBox.Show("it's done");
                return;
            }

            win.execScript(string.Format("subpage({0});", ++count), "javascript"); //执行分页js
        }