在.NET中使用JQuery 選擇器精確提取網頁內容


1. 前言

   相信很多人做開發時都有過這樣的需求:從網頁中准確提取所需的內容。思前想后,方法無非是以下幾種:(本人經驗尚淺,有更好的方法還請大家指點)

   1. 使用正則表達式匹配所需元素。(缺點:同類型的元素如果有不同的屬性,比如<div class='first'>aaa</div><div class='last'>bbb</div>, 如果想要匹配所有div元素時,將會相當麻煩,而且容易得到不想要的結果,漏掉需要的結果。)

   2. 將網頁轉換成XML文檔,使用Linq to XML。(缺點:需要一次轉換過程,而且效率不高。)

   3. 使用網站提供的WebServices或WebAPI等接口直接獲取所需數據。(缺點:需要先獲得接口文檔,一般都不會匿名提供。)

 

   最近幾年前端的興起,越來越多的人開始認識JQuery這個強大的工具並被其折服,其中很重要的一點就是JQuery 選擇器,它的簡潔,高效,易學使得前端工程師大大提高了工作效率。細想一下,提取網頁內容就是和前端打交道,如果可以用JQuery選擇器,那就完美了!!!

 

2. 理論准備

    難道要在.NET下自己去做一個選擇器?非也,這可不是我等小輩能做出來的。。。。既然已經有JQuery了,為什么不能直接就用它的選擇器呢?

    1. .NET獲得網頁內容

        這里可以選擇webbrowser控件,其實它就是一個微型IE,IE能做的它都能做。有些人會問為什么不用WebClient直接下載網頁內容呢?請看第二點。

    2. .NET與JS交互

        使用webbrowser控件,不僅可以獲得網頁內容,更加重要的是它提供了與網頁交互的功能。使用內置的Document屬性,我們可以往網頁中注入所需的JS代碼並且執行它。

    3. 提取並返回所需內容

        在.NET中,我們可以用Docment的InvokeScript函數來執行相應的JS函數並獲得返回結果。

     既然理論都准備好了,接下來我們就實現它吧。

 

3. 功能實現

    測試網頁:http://www.mmeinv.com/    (福利網站哦,不過絕無邪惡內容,請編輯明鑒!)

    功能需求:提取所有“福利”!!!!

    先上圖:

    

 

   

 

    從圖上可以看出,“福利”都准確地提取出來了。並且可以只獲取所需的屬性值。你要做的只是輸入短短的15個字符。

    下面再看看代碼實現:

    其中wb就是webbrowser控件,此段主要為了在一些不包括JQuery庫的網頁中注入JQuery庫。

        void InjectJQuery()
        {
            HtmlElement jquery = wb.Document.CreateElement("script");
            jquery.SetAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js");
            wb.Document.Body.AppendChild(jquery);
            JQueryInjected = true;
        }

 

    這里是注入需要執行的JS函數,因為不同的需求有不同的代碼,所以不能重復注入,需求改變時只需要更改已注入的函數即可以。

                    JQScript = wb.Document.GetElementById("JQScript");

                    if (JQScript == null)
                    {
                        JQScript = wb.Document.CreateElement("script");
                        JQScript.SetAttribute("id", "JQScript");
                        JQScript.SetAttribute("type", "text/javascript");
                        wb.Document.Body.AppendChild(JQScript);
                    }

 

   這里是關鍵代碼, 根據是否要提取屬性而生成不同的代碼。注入的代碼非常簡單,相信懂一點點前端的朋友一看就明白了。而最后的一行代碼就是執行注入的函數並獲取返回值。

                    if (txtAttribute.Text.Trim() == string.Empty)
                        JQScript.SetAttribute("text", "function GetJQValue() { if ($('" + txtSelector.Text + "').length == 1) {" +
                                                                                "return $('" + txtSelector.Text + "')[0].outerHTML; }" +
                                                                                " else if ($('" + txtSelector.Text + "').length > 1) {" +
                                                                                " var allhtml = '';" +
                                                                                " $('" + txtSelector.Text + "').each(function() {allhtml=allhtml+$(this)[0].outerHTML+'\\r\\n';});" +
                                                                                " return allhtml;}" +
                                                                                " else return 'no item found.';}");
                    else
                    {
                        JQScript.SetAttribute("text", "function GetJQValue() { if ($('" + txtSelector.Text + "').length == 1) {" +
                                                                                "return $('" + txtSelector.Text + "').attr('" + txtAttribute.Text + "'); }" +
                                                                                " else if ($('" + txtSelector.Text + "').length > 1) {" +
                                                                                " var allhtml = '';" +
                                                                                " $('" + txtSelector.Text + "').each(function() {allhtml=allhtml+$(this).attr('" + txtAttribute.Text + "')+'\\r\\n';});" +
                                                                                " return allhtml;}" +
                                                                                " else return 'no item found.';}");
                    }
                    textBox2.Text = wb.Document.InvokeScript("GetJQValue").ToString();

 

  相信到這里,大家都已經一目了然,短短10幾行代碼,就可以使用強大的JQuery選擇器,效率比以前的舊方法高了不知多少倍,何樂而不為呢?

 

4. 知識延伸

     1. 只要你前端知識夠硬,就可以注入更復雜的函數,實現更復雜的內容提取。

     2. 在Android和IOS里,理論上也是可以實現這樣的功能。

     3. 也許有一天,我們會有類似的選擇器去代替SQL,實現數據庫的高效查詢??????????

 

PS: 小弟文筆極差,知識面不廣,如有紕漏,請大家斧正!

PPS:啰嗦也要說了,文章版權本人所有,轉載請明確標示並保留原文鏈接,謝謝大家!

 

Demo及源代碼: http://files.cnblogs.com/XiaoFaye/JQuerySelector.zip


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM