.net 信息採集ajax數據

.net 信息採集ajax數據javascript

關於.net信息採集的資料不少,可是若是採集的網站是ajax異步加載數據的模式,又如何採集呢?今天就把本身作信息採集時,所遇到的一些問題和心得跟你們分享一下。html

採集網站的幾種方式與利弊:java

  1. HttpWebRequest

利用系統自帶HttpWebRequest對象,採集網站內容,優勢是採集效率快,可是若是網站是ajax異步加載數據的方式,是採集不到網頁內容的,而且網站沒有采用ajax的方式,在網頁中用到了javascript,好比說:網頁內容用document.write的方式輸出到網頁中的,這種狀況也是獲取不到內容的。其次還須要知道對方網站的編碼格式(就是網頁頭部中<meta charset="utf-8"/>),若是採集時網站編碼格式錯誤的話,會致使採集的內容是亂碼。但這個是小問題,我本身當時查閱資料時找到了別人封裝好的方法,可是很慚愧由於不知道做者是誰了,我會把相應的代碼下載連接提供給你們。以上的問題是由於js和ajax是須要瀏覽器去解析的,因此致使了獲取不到網頁內容。web

Help.HttpHelp.HttpRequest("採集的網址");

源碼下載地址ajax

          2.瀏覽器控件瀏覽器

由於當時我開發的時候,用的是cs模式,相信你們一樣也會用cs的模式去開發這個功能。既然是cs模式(不考慮美觀)的狀況下確定是WinForm,WinForm中有自帶的瀏覽器控件,這個是很差用的,我當時用的是Geckofx,基於火狐內核的一款瀏覽器控件,可是這方面的資料不多,當時遇到了一些問題都找不到解決方法,但後來仍是都解決了。用了該控件就能夠獲取到ajax異步加載的數據,在網頁加載完成以後,延遲幾秒鐘獲取網頁內容,就能夠很方便的獲取到網頁內容,缺點是相對第一種方案來講的話會慢一些,由於它是一個瀏覽器控件,須要渲染html和解析js等操做。異步

Geckofx下載網站

GeckoWebBrowser webBrowser = null;

        private void Form1_Load(object sender, EventArgs e)
        {
            string xulrunnerPath = AppDomain.CurrentDomain.BaseDirectory + "\\bin";
            Xpcom.Initialize(xulrunnerPath);
            //設置爲3阻止全部的彈出窗口,
            GeckoPreferences.User["privacy.popups.disable_from_plugins"] = 3;
            //禁止加載圖片
            GeckoPreferences.User["permissions.default.image"] = 2;

            webBrowser = new GeckoWebBrowser();
            webBrowser.Navigate("http://www.baidu.com");
            webBrowser.DocumentCompleted += DocumentCompleted;
        }

        private void DocumentCompleted(object sender, Gecko.Events.GeckoDocumentCompletedEventArgs e)
        {
            var time = new System.Windows.Forms.Timer();
            time.Interval = 2000;
            time.Tick += (a, b) =>
            {
                time.Stop();
                string html = "";
                //頁加載完成
                GeckoHtmlElement element = null;
                var geckoDomElement = webBrowser.Document.DocumentElement;
                if (geckoDomElement != null && geckoDomElement is GeckoHtmlElement)
                {
                    element = (GeckoHtmlElement)geckoDomElement;
                    //網頁內容
                    html = element.InnerHtml;
                    txtHtml.Text = html;
  /*
                    //經過xpath 查找class爲btnLogin的元素
                    GeckoNode btnLogin = webBrowser.Document.SelectFirst(".//*[@class='btnLogin']");
                    if (btnLogin != null)
                    {
                        GeckoHtmlElement ie = btnLogin as GeckoHtmlElement;
                        //手動觸發點擊事件
                        ie.Click();
                    }*/ } }; time.Start(); }

 

         3.phantomjsui

phantomjs能夠把它理解爲也是一個瀏覽器控件,只不過它使用QtWebKit做爲它核心瀏覽器的功能,使用webkit來編譯解釋執行JavaScript代碼。利用該組件就能夠很方便的獲取到網頁內容,同時也包括了ajax加載的數據,若是是分頁的狀況下,首次加載不須要延遲,若是獲取第2頁及以上內容的話一樣也須要延遲才能獲取到,而且它能夠很方便的完成網頁快照(就是網頁截屏),至於其餘的功能你們能夠本身查閱一下資料。編碼

phantomjs下載地址

  IWebDriver driver = null;

        private void btnGo_Click(object sender, EventArgs e)
        {
            string phantomjsDire = AppDomain.CurrentDomain.BaseDirectory;

            PhantomJSDriverService service = PhantomJSDriverService.CreateDefaultService(phantomjsDire);
            service.IgnoreSslErrors = true;
            service.LoadImages = false;
            service.ProxyType = "none";

            driver = new PhantomJSDriver(phantomjsDire);
            /*IWindow iWindow = driver.Manage().Window;
            iWindow.Size = new Size(10,10);
            iWindow.Position = new Point(0, 600);*/

            driver.Navigate().GoToUrl(textBox1.Text);
            string html = driver.PageSource;
            txtHtml.Text = html;

            //driver.Close();
            //driver.Quit();
        }

        private void btnPage_Click(object sender, EventArgs e)
        {
            //  .//*[@class='next'][text()='下一頁']
            //  .//*[@class='text']
            //  .//*[@class='button']
            //IWebElement element = driver.FindElement(By.XPath(".//*[@class='text']"));
            //給網頁中文本框賦值
            //element.SendKeys("4");

            IWebElement btnElement = driver.FindElement(By.XPath(".//*[@class='next'][text()='下一頁']"));
            btnElement.Click();

            var time = new System.Windows.Forms.Timer();
            time.Interval = 2 * 1000;
            time.Tick += (a, b) =>
            {
                time.Stop();
                string html = driver.PageSource;
                txtHtml.Text = html;
            };
            time.Start();
        }

 網站內容中url地址若是是相對地址的話,就是../../a.html,這種狀況要想獲取絕對地址的話,能夠用如下方法:

        /// <summary>
        /// 獲取絕對url地址
        /// </summary>
        /// <param name="baseUri">當前頁地址</param>
        /// <param name="relativeUri">相對路徑地址</param>
        /// <returns></returns>
        public static string GetRealUrl(string baseUri, string relativeUri)
        {
            try
            {
                baseUri = System.Web.HttpUtility.UrlDecode(baseUri);
                relativeUri = System.Web.HttpUtility.UrlDecode(relativeUri);
                Uri baseUriModel = new Uri(baseUri);
                Uri uri = new Uri(baseUriModel, relativeUri);
                string result = uri.ToString();
                baseUriModel = null;
                uri = null;
                return result;
            }
            catch (Exception ex)
            {
            }
            return relativeUri;
        }

 

  總結:

以上說的第二、3種方式均可以獲取到ajax異步加載的內容,同時還能經過xpath模式查找網頁中的元素,例如分頁標籤和按鈕,找到元素以後能夠調用click點擊事件,就能輕鬆的解決分頁問題。好多網站分頁分到最後一頁的時候,處理的狀況都不同,須要本身去處理,例若有的隱藏下一頁按鈕、有的是禁用等等。

獲取到網頁內容以後,要想獲取本身須要的內容,能夠經過HtmlAgilityPack插件,它是經過xpath的模式查找內容。

如下我會將本身開發的信息採集系統截圖發出來。

 

歡迎任何形式的轉載,但請務必註明出處。

文案功底有限,碼字不易,不喜勿噴,若是文章和代碼有表述不當之處,還請不吝賜教。

相關文章
相關標籤/搜索