相信不少人作開發時都有過這樣的需求:從網頁中準確提取所需的內容。思前想後,方法無非是如下幾種:(本人經驗尚淺,有更好的方法還請你們指點)javascript
1. 使用正則表達式匹配所需元素。(缺點:同類型的元素若是有不一樣的屬性,好比<div class='first'>aaa</div><div class='last'>bbb</div>, 若是想要匹配全部div元素時,將會至關麻煩,並且容易獲得不想要的結果,漏掉須要的結果。)html
2. 將網頁轉換成XML文檔,使用Linq to XML。(缺點:須要一次轉換過程,並且效率不高。)前端
3. 使用網站提供的WebServices或WebAPI等接口直接獲取所需數據。(缺點:須要先得到接口文檔,通常都不會匿名提供。)java
最近幾年前端的興起,愈來愈多的人開始認識JQuery這個強大的工具並被其折服,其中很重要的一點就是JQuery 選擇器,它的簡潔,高效,易學使得前端工程師大大提升了工做效率。細想一下,提取網頁內容就是和前端打交道,若是能夠用JQuery選擇器,那就完美了!!!jquery
難道要在.NET下本身去作一個選擇器?非也,這可不是我等小輩能作出來的。。。。既然已經有JQuery了,爲何不能直接就用它的選擇器呢?web
1. .NET得到網頁內容ajax
這裏能夠選擇webbrowser控件,其實它就是一個微型IE,IE能作的它都能作。有些人會問爲何不用WebClient直接下載網頁內容呢?請看第二點。正則表達式
2. .NET與JS交互數據庫
使用webbrowser控件,不只能夠得到網頁內容,更加劇要的是它提供了與網頁交互的功能。使用內置的Document屬性,咱們能夠往網頁中注入所需的JS代碼而且執行它。api
3. 提取並返回所需內容
在.NET中,咱們能夠用Docment的InvokeScript函數來執行相應的JS函數並得到返回結果。
既然理論都準備好了,接下來咱們就實現它吧。
測試網頁: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選擇器,效率比之前的舊方法高了不知多少倍,何樂而不爲呢?
1. 只要你前端知識夠硬,就能夠注入更復雜的函數,實現更復雜的內容提取。
2. 在Android和IOS裏,理論上也是能夠實現這樣的功能。
3. 也許有一天,咱們會有相似的選擇器去代替SQL,實現數據庫的高效查詢??????????
PS: 小弟文筆極差,知識面不廣,若有紕漏,請你們斧正!
PPS:囉嗦也要說了,文章版權本人全部,轉載請明確標示並保留原文連接,謝謝你們!
Demo及源代碼: http://files.cnblogs.com/XiaoFaye/JQuerySelector.zip