国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
用Javascript解析html

該文章有更新,請移步 http://pickerel.iteye.com/admin/blogs/267912

 

說到用Javascript解析html,大家肯定會想到dom或者正則表達式,但這兩個都不是我今天我要說的。dom很不錯,不過效率不高,而且必須將要解析的html插入到當前頁面或者建立一個iframe才能進行,而用正則表達式,又有太過繁瑣和難以維護的問題。

 

有人要說了,ruby、php、python有了那么多開源的優(yōu)秀的html解析的類庫,什么beautiful soap,什么Mechanize,什么Hpricot,什么ScRUBYt,你為什么非要自討苦吃用javascript來干這活呢?

 

答案是:如果只允許你用javascript和html開發(fā)程序呢,比如開發(fā)adobe air的程序,比如下一步我要做的基于基于內(nèi)嵌webkit組件的Android應用快速開發(fā)框架,有時候,輪子還是得自己造的。

 

我的這個解析實現(xiàn)只是雛形,它以Erik Arvidsson開發(fā)的SimpleHtmlParser作為html的分析器。SimpleHtmlParser是一個基于Sax模型實現(xiàn)的html分析器,他能分析非標準的xml的格式的html別把轉(zhuǎn)換作為一個標準的xml處理。有了這個解析器做基礎,我寫了個簡單的html_extractor,用來分析html并獲取指定標記內(nèi)的內(nèi)容。

 

html_extractor的使用

 

new html_extractor(html): 指定html字符串創(chuàng)建一個html_extractor對象

方法:

tag(tagName):設定一個待匹配的元素名,返回結果為當面的html_extractor對象

attr(attrName, attrValue):設定匹配的屬性條件,attr必須在tag后,返回結果為當面的html_extractor對象

match(innerOrNot):執(zhí)行匹配,返回結果為符合條件的字符串數(shù)組。

示例:

 

Js代碼  
  1. html = "<div>div1</div>";  
  2. //取出div標記下的內(nèi)容,ret的結果是["div1"]  
  3. var ret = new html_extractor(html).tag("div").match();  
  4.   
  5. html = "<div id=\"head\">head</div><div id=\"content\"><p><ul><li>item1</li><li>item2</li></ul></div>";         
  6. //取出屬性id=content的div下的所有l(wèi)i下的內(nèi)容,返回結果將是["item1", "item2"]  
  7. ret = new html_extractor(html).tag("div").attr("id""content").tag("li").match();  
  8.   
  9. //提取baidu搜索結果  
  10. ret = new html_extractor(html).tag("td").attr("class""f").match();  
  11. //提取google搜索結果  
  12. ret = new html_extractor(html).tag("li").attr("class""g").match();  

 

源代碼(當前代碼還非常原始,進攻參考,請慎重使用)

Js代碼  
  1. var html_extractor = function(html)  
  2. {  
  3.     this.parser = new SimpleHtmlParser;  
  4.     this.html  = html;  
  5.     this.tags = [];  
  6.     this.attrs = [];      
  7. }  
  8. html_extractor.prototype.tag = function(tag)  
  9. {  
  10.     this.tags.push(tag.toLowerCase());  
  11.   
  12.     return this;  
  13. }  
  14. html_extractor.prototype.attr = function(name, value)  
  15. {  
  16.     var len = this.tags.length - 1;  
  17.     if (this.attrs[len] == undefined)this.attrs[len] = [];  
  18.     this.attrs[len].push({name:name.toLowerCase(), value: value});  
  19.     return this;  
  20. }  
  21. html_extractor.prototype.match = function(inner)  
  22. {  
  23.     var self = this;  
  24.     var handler = function(){  
  25.         this._tag_index = 0;  
  26.         this._matched_tags = [];  
  27.         this._matched = [];  
  28.         this._result = "";  
  29.         this.result = [];  
  30.         this._all_matched = false;  
  31.         forvar i = 0; i < self.tags.length; i++)this._matched[i] = false;  
  32.         this.inner = true;  
  33.         if (inner != undefined && inner != null)  
  34.         {  
  35.             this.inner = inner;  
  36.         }  
  37.   
  38.     };  
  39.     handler.prototype = {  
  40.         startElement:   function (tag, attrs) {  
  41.             this.tag_index++;  
  42.             tag = tag.toLowerCase();  
  43.             //air.trace("process tag:" + tag +  " " + this.tag_index);  
  44.   
  45.             if (this._all_matched )  
  46.             {  
  47.                 this._result += get_start_tag(tag, attrs);  
  48.                 return;  
  49.             }  
  50.   
  51.             forvar i = 0; i < this._matched.length; i++)  
  52.             {  
  53.                 //air.trace(i + ":" + this._matched[i]);  
  54.                 if (!this._matched[i] )  
  55.                 {  
  56.                     if (self.tags[i] == tag)  
  57.                     {  
  58.                         this._matched[i] = true;  
  59.                         if (self.attrs[i] != undefined)  
  60.                         {  
  61.                             for(var n = 0; n < self.attrs[i].length; n++)  
  62.                             {  
  63.                                 var attr = self.attrs[i][n];  
  64.                                 if (attr != undefined)  
  65.                                 {  
  66.                                     if(attrs[attr.name] != attr.value)  this._matched[i] = false;  
  67.                                 };  
  68.                             }  
  69.                         }  
  70.                         if (this._matched[i] )  
  71.                         {  
  72.                              //todo callback  
  73.                              //air.trace(i + ":" + this._matched[i] + " first");  
  74.                              this._matched_tags[this.tag_index] = i;  
  75.                              if (i == self.tags.length -1)  
  76.                              {  
  77.                                  this._all_matched = true;  
  78.                                  if (!this.inner) this._result += get_start_tag(tag, attrs);  
  79.                              }  
  80.                              return;  
  81.                         }  
  82.                     }  
  83.   
  84.                     if (!this._matched[i] ){break;}  
  85.   
  86.                 }  
  87.             }         
  88.         },  
  89.         endElement:     function (tag) {  
  90.             tag = tag.toLowerCase();  
  91.   
  92.             if (this._matched_tags[this.tag_index] != undefined)  
  93.             {  
  94.                 this._matched[this._matched_tags[this.tag_index]] = false;  
  95.                 if (this._all_matched)  
  96.                 {  
  97.                     if (!this.inner)this._result += "</" + tag +">";  
  98.                     this.result.push(this._result);  
  99.                     this._result = "";  
  100.                     this._all_matched = false;  
  101.                 }  
  102.             }  
  103.             else if (this._all_matched)  
  104.             {  
  105.                 this._result += "</" + tag +">";  
  106.             }  
  107.             //air.trace("finished tag:" + tag +  " " + this.tag_index);  
  108.   
  109.             this.tag_index--;  
  110.         },  
  111.         characters:     function (s) { if(this._all_matched)this._result += s;},  
  112.         comment:        function (s) {}  
  113.     };  
  114.     this.parser.contentHandler = new handler;  
  115.   
  116.     this.parser.parse(this.html);     
  117.     //reset  
  118.     this.tags = [];  
  119.     this.attrs = [];  
  120.     return this.parser.contentHandler.result;  
  121. }  
  122. function get_start_tag(tag, attrs)  
  123. {  
  124.     var ret = "<" + tag;  
  125.     for (var key in attrs)  
  126.     {  
  127.         value = attrs[key];  
  128.         ret += " " + key + "=\"" + value + "\"";  
  129.   
  130.     }  
  131.     ret += ">";  
  132.     return ret;  
  133. }  
  134.   
  135. /** SimpleHtmlParser 
  136.  * Original code by Erik Arvidsson, Mozilla Public License 
  137.  * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js 
  138.  */  
  139.   
  140. /* 
  141. var handler ={ 
  142.     startElement:   function (sTagName, oAttrs) {}, 
  143.     endElement:     function (sTagName) {}, 
  144.     characters:     function (s) {}, 
  145.     comment:        function (s) {} 
  146. }; 
  147. */  
  148.   
  149. function SimpleHtmlParser()  
  150. {  
  151. }  
  152.   
  153. SimpleHtmlParser.prototype = {  
  154.   
  155.     handler:    null,  
  156.   
  157.     // regexps  
  158.   
  159.     startTagRe: /^<([^>\s\/]+)((\s+[^=>\s]+(\s*=\s*((\"[^"]*\")|(\'[^']*\')|[^>\s]+))?)*)\s*\/?\s*>/m,  
  160.     endTagRe:   /^<\/([^>\s]+)[^>]*>/m,  
  161.     attrRe:     /([^=\s]+)(\s*=\s*((\"([^"]*)\")|(\'([^']*)\')|[^>\s]+))?/gm,  
  162.   
  163.     parse:  function (s, oHandler)  
  164.     {  
  165.         if (oHandler)  
  166.             this.contentHandler = oHandler;  
  167.   
  168.         var i = 0;  
  169.         var res, lc, lm, rc, index;  
  170.         var treatAsChars = false;  
  171.         var oThis = this;  
  172.         while (s.length > 0)  
  173.         {  
  174.             // Comment  
  175.             if (s.substring(0, 4) == "<!--")  
  176.             {  
  177.                 index = s.indexOf("-->");  
  178.                 if (index != -1)  
  179.                 {  
  180.                     this.contentHandler.comment(s.substring(4, index));  
  181.                     s = s.substring(index + 3);  
  182.                     treatAsChars = false;  
  183.                 }  
  184.                 else  
  185.                 {  
  186.                     treatAsChars = true;  
  187.                 }  
  188.             }  
  189.   
  190.             // end tag  
  191.             else if (s.substring(0, 2) == "</")  
  192.             {  
  193.                 if (this.endTagRe.test(s))  
  194.                 {  
  195.                     lc = RegExp.leftContext;  
  196.                     lm = RegExp.lastMatch;  
  197.                     rc = RegExp.rightContext;  
  198.   
  199.                     lm.replace(this.endTagRe, function ()  
  200.                     {  
  201.                         return oThis.parseEndTag.apply(oThis, arguments);  
  202.                     });  
  203.   
  204.                     s = rc;  
  205.                     treatAsChars = false;  
  206.                 }  
  207.                 else  
  208.                 {  
  209.                     treatAsChars = true;  
  210.                 }  
  211.             }  
  212.             // start tag  
  213.             else if (s.charAt(0) == "<")  
  214.             {  
  215.                 if (this.startTagRe.test(s))  
  216.                 {  
  217.                     lc = RegExp.leftContext;  
  218.                     lm = RegExp.lastMatch;  
  219.                     rc = RegExp.rightContext;  
  220.   
  221.                     lm.replace(this.startTagRe, function ()  
  222.                     {  
  223.                         return oThis.parseStartTag.apply(oThis, arguments);  
  224.                     });  
  225.   
  226.                     s = rc;  
  227.                     treatAsChars = false;  
  228.                 }  
  229.                 else  
  230.                 {  
  231.                     treatAsChars = true;  
  232.                 }  
  233.             }  
  234.   
  235.             if (treatAsChars)  
  236.             {  
  237.                 index = s.indexOf("<");  
  238.                 if (index == -1)  
  239.                 {  
  240.                      this.contentHandler.characters(s);  
  241.                     s = "";  
  242.                 }  
  243.                 else  
  244.                 {  
  245.                     this.contentHandler.characters(s.substring(0, index));  
  246.                     s = s.substring(index);  
  247.                 }  
  248.             }  
  249.   
  250.             treatAsChars = true;  
  251.         }  
  252.     },  
  253.   
  254.     parseStartTag:  function (sTag, sTagName, sRest)  
  255.     {  
  256.         var attrs = this.parseAttributes(sTagName, sRest);  
  257.         this.contentHandler.startElement(sTagName, attrs);  
  258.     },  
  259.   
  260.     parseEndTag:    function (sTag, sTagName)  
  261.     {  
  262.         this.contentHandler.endElement(sTagName);  
  263.     },  
  264.   
  265.     parseAttributes:    function (sTagName, s)  
  266.     {  
  267.         var oThis = this;  
  268.         var attrs = {};  
  269.         s.replace(this.attrRe, function (a0, a1, a2, a3, a4, a5, a6)  
  270.         {  
  271.             //attrs.push(oThis.parseAttribute(sTagName, a0, a1, a2, a3, a4, a5, a6));  
  272.             attr = oThis.parseAttribute(sTagName, a0, a1, a2, a3, a4, a5, a6);  
  273.             attrs[attr.name] = attr.value;  
  274.         });  
  275.         return attrs;  
  276.     },  
  277.   
  278.     parseAttribute: function (sTagName, sAttribute, sName)  
  279.     {  
  280.         var value = "";  
  281.         if (arguments[7])  
  282.             value = arguments[8];  
  283.         else if (arguments[5])  
  284.             value = arguments[6];  
  285.         else if (arguments[3])  
  286.             value = arguments[4];  
  287.   
  288.         var empty = !value && !arguments[3];  
  289.         return {name: sName.toLowerCase(), value: empty ? null : value};  
  290.     }  
  291. };  

 

 

 

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
javascript中的NodeType、NodeValue、NodeName實例測試
網(wǎng)頁鏈接提取
閉包問題
PHP讀取sphinx實例
讀《Javascript高級程序設計(第3版)》部分章節(jié)后,修正之前對閉包的誤解,并提出疑問
javascript 正則表達式判斷中文
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服