亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: 發(fā)布一個(gè)HTML正文提取程序PHP版 HTMLExtractor [打印本頁]

作者: xjtdy888    時(shí)間: 2010-12-19 23:18
標(biāo)題: 發(fā)布一個(gè)HTML正文提取程序PHP版 HTMLExtractor
本帖最后由 xjtdy888 于 2010-12-19 23:25 編輯

發(fā)布一個(gè)HTML正文提取程序HTMLExtractor,在線例子
http://dev.psm01.cn/c/html-extractor.php
程序主要是基于內(nèi)容統(tǒng)計(jì)的方法,暫不包含自學(xué)習(xí)能力,僅是
一個(gè)分析程序而以,網(wǎng)上也有別人實(shí)現(xiàn)了的正文提取程序,不過
大部人都當(dāng)寶,都不愿意公開完整代碼,有些大人實(shí)現(xiàn)了一些簡
單的,不過分析能力和識(shí)別能力都不太理想。所以自己做了一個(gè)
簡單的,本來想用PHP DOM分析器,不過大部份網(wǎng)頁都不規(guī)范,
缺個(gè)標(biāo)簽啥的都很正常,所以自已又造了個(gè)簡單的輪子分析HTML標(biāo)
簽,功能比較簡單,每個(gè)元素都生成一個(gè)對(duì)象,內(nèi)存方面占用比較
高,不過在這里我只是為了實(shí)現(xiàn),并沒去做優(yōu)化。因?yàn)槲也⒉皇窃?br /> 做應(yīng)用,所以希望不要讓我改改成什么樣去適用你們的業(yè)務(wù)(以前經(jīng)常
有QQ加上讓我把我的例子怎么改,很無語),
如果你們喜歡,可以和我一起開發(fā)完善他。

補(bǔ)充一下,因?yàn)閷懙闹保F(xiàn)在幾個(gè)類的耦合性還比較大,下來再守善吧。

項(xiàng)目代碼 http://code.google.com/p/html-extractor/
QQ 339534039
郵箱 xjtdy888[at]163.com
BLOG http://hi.baidu.com/phps
  1. <?php
  2. /**
  3. *
  4. * 作者 言兌
  5. * 郵箱 xjtdy888[at]163.com
  6. * QQ 339534039
  7. * 項(xiàng)目托管 http://code.google.com/p/html-extractor/
  8. *
  9. */
  10. error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
  11. header("Content-type:text/html; charset=utf-8");
  12. $url = $_REQUEST['url'];
  13. $v = $url ? $url : 'http://news.sina.com.cn/w/2010-11-03/063821404648.shtml';
  14. echo '<title>正文提取</title>';
  15. echo '<h3>PHP 網(wǎng)頁正文提取程序</h2>';
  16. echo '<h3>作者: 言兌</h2>';
  17. echo '<h3>QQ: 339534039</h2>';
  18. echo '<h3> <a href="http://hi.baidu.com/phps" target="_blank">查看博客</a> <a href="http://code.google.com/p/html-extractor/" target="_blank">查看項(xiàng)目代碼</a></h3>';
  19. echo '<form>';
  20. echo '請(qǐng)輸入要提取的URL:<input type="text" name="url" size="50" value="'.$v.'" /><input type="submit" value="分析" />';
  21. echo '</form>';
  22. if (!$url){
  23.         exit;
  24. }
  25. echo '<b>分析結(jié)果:</b> <a href="'.$url.'" target="_blank">查看原文</a>:<br /><br />';

  26. $text = HTMLExtractor::getUrlMainContent($url,200,1);
  27. $text = HTMLExtractor::convertToUTF8($text);
  28. if (!$text) $text = "抓取失敗...可能目標(biāo)頁不規(guī)范或者正文太短";

  29. echo ($text);

  30. echo "<br /><br />耗時(shí):" . HTMLExtractor::$usageTime;
  31. if (function_exists('memory_get_usage')){
  32.         echo "內(nèi)存占用:" . (memory_get_usage(true)/1024).'KB';
  33. }

  34. class HTMLExtractor
  35. {
  36.         #要?jiǎng)h掉的元素
  37.         const PC_TAG_DELETE = 1;
  38.         #要?jiǎng)h掉的標(biāo)簽
  39.         const PC_TAG_STRIP = 2;
  40.         static $cleanTags= array(
  41.                 array("script",self::PC_TAG_DELETE),
  42.                 array("style",self::PC_TAG_DELETE),
  43.                 array("link",self::PC_TAG_DELETE),
  44.                 array("link",self::PC_TAG_DELETE),
  45.                 array("object",self::PC_TAG_DELETE),
  46.                 array("embed",self::PC_TAG_DELETE),


  47.                 array("p",self::PC_TAG_STRIP),
  48.                 array("b",self::PC_TAG_STRIP),
  49.                 array("i",self::PC_TAG_STRIP),
  50.                 array("u",self::PC_TAG_STRIP),
  51.                 array("font",self::PC_TAG_STRIP),
  52.                 array("strong",self::PC_TAG_STRIP),
  53.         );
  54.         static $usageTime = 0;
  55.         static function preClean($html)
  56.         {
  57.                 foreach(self::$cleanTags as $t)
  58.                 {
  59.                         if (!$t) continue;
  60.                         $name = $t[0];
  61.                         $pc   = $t[1];
  62.                         $html = preg_replace("#<({$name})(>|\s[^>]*?>)(.*?)</\\1>#is",
  63.                                 $pc == self::PC_TAG_DELETE ? "" : "\\3",$html);                               
  64.                 }
  65.                 return $html;

  66.         }
  67.         static function getDataMainContent($data,$minlength,$maxdepth)
  68.         {
  69.                 $s = microtime(true);
  70.                 $data = self::preClean($data);
  71.                 $root = new htmlTag("document",htmlTag::DOM_TAG);
  72.                 $hand = new htmlExtractorHandler($root);
  73.                 $p = new htmlParse($data,$hand);
  74.                 $p->parse();
  75.                 $text =  self::getMainContent($root,$minlength,$maxdepth);
  76.                 $e = microtime(true);
  77.                 self::$usageTime = $e - $s;
  78.                 return $text;
  79.         }
  80.         static function getUrlMainContent($url,$minlength,$maxdepth)
  81.         {
  82.                 $data = self::getUrlHtml($url);
  83.                 if (!$data) return false;
  84.                 return self::getDataMainContent($data,$minlength,$maxdepth);
  85.         }
  86.         static function getDomText($dom,$depth)
  87.         {
  88.                 if ($dom->echoset) return ;
  89.                 $dom->echoset = true;
  90.                 if($dom->depth <= $depth){
  91.                         foreach($dom->getChildren() as $child){
  92.                                 if (is_object($child)){
  93.                                         $result .= self::getDomText($child,$depth);
  94.                                 }elseif(is_string($child)){
  95.                                         $result .= $child;
  96.                                 }
  97.                         }
  98.                 }
  99.                 return $result;
  100.         }

  101.         static function getMainContent($root,$textLength=100,$maxdepth)
  102.         {

  103.                 $result = '';
  104.                 $cn  = $root->tagNum + $root->textNum;
  105.                 $per = $root->tagNum ? $root->textLength/$textLength / $root->tagNum : 1;
  106.                 if ($root->textLength >= $textLength && $per>0.5){
  107.                         $result .= self::getDomText($root,$root->depth+$maxdepth);
  108.                 }
  109.                 foreach($root->getChildren() as $dom){
  110.                         if (is_object($dom)){
  111.                                 $result .= self::getMainContent($dom,$textLength,$maxdepth);
  112.                         }
  113.                 }
  114.                 return $result;
  115.         }

  116.        
  117.         static function checkTextType($url)
  118.         {  
  119.                 $url = parse_url($url);
  120.                 if($fp = @fsockopen($url['host'],empty($url['port'])?80:$url['port'],$error))
  121.                 {
  122.                         fputs($fp,"GET ".(empty($url['path'])?'/':$url['path'])." HTTP/1.1\r\n");
  123.                         fputs($fp,"Host:$url[host]\r\n\r\n");
  124.                         while(!feof($fp))
  125.                         {
  126.                                 $tmp = fgets($fp);
  127.                                 if(trim($tmp) == ''){
  128.                                         break;
  129.                                 }else if(preg_match('#Content-type: text/(.*)#si',$tmp,$arr)){
  130.                                         fclose($fp);
  131.                                         return true;
  132.                                 }
  133.                         }
  134.                         fclose($fp);
  135.                         return false;
  136.                 }else{
  137.                         return false;
  138.                 }
  139.         }

  140.         static function convertToUTF8($str) {
  141.                 $charset = mb_detect_encoding($str, array('ASCII','UTF-8','GB2312','GBK','BIG5','ISO-8859-1'));
  142.                 if (strcasecmp($charset,'UTF-8') != 0) {
  143.                         $str = mb_convert_encoding($str,'UTF-8',$charset);
  144.                 }
  145.                 return $str;
  146.         }


  147.         static function getUrlHtml($url){
  148.                 //return file_get_contents("txt.txt");
  149.                 if (!self::checkTextType($url)){
  150.                         exit();
  151.                 }
  152.                 return file_get_contents($url);
  153.         }
  154. }
  155. /**
  156. *
  157. * HTML 標(biāo)簽解析器
  158. * 該解析器以<>為單元 比如 <div id="cc"> 這是一個(gè)處理單元
  159. * 所以 <div></div> 這句是2個(gè)處理單元<div>和</div>
  160. * 解析器每處理一個(gè)單元都會(huì)產(chǎn)生回調(diào)函數(shù),至于怎么來處理這個(gè)單元由處理器來決定
  161. * 也就是說該解析器并不去處理標(biāo)簽匹不匹配之類的問題
  162. * </span></span> 這樣的字符串也是可以進(jìn)行解析的,產(chǎn)生2次 endElement 事件回調(diào)。
  163. * 本來先用PHP自帶的DOM對(duì)象類,不過由于大部份網(wǎng)頁都不規(guī)范,解析起來大部份是會(huì)出錯(cuò)的
  164. * 所以自己寫了這個(gè)簡單的
  165. * 本類總共3個(gè)回調(diào)函數(shù)
  166. *  startElement($parser,$tagName)        發(fā)現(xiàn)開始標(biāo)簽
  167. *  endElement($parser,$tagName)        發(fā)現(xiàn)閉合標(biāo)簽
  168. *  characterData($parser,$char)        發(fā)現(xiàn)標(biāo)簽內(nèi)容
  169. *  本類沒做任何優(yōu)化,所以回調(diào)的頻率會(huì)相當(dāng)?shù)母摺?br />
  170. *
  171. */
  172. class htmlParse
  173. {
  174.         /**
  175.          *        要處理的HTML內(nèi)容
  176.          */
  177.         protected $_html = '';
  178.         /**
  179.          * _html 的長度
  180.          */
  181.         protected $_htmlLength = 0;
  182.         /**
  183.          * 當(dāng)前處理位置指針
  184.          */
  185.         protected $_pt = 0;
  186.         /**
  187.          * 標(biāo)簽狀態(tài)棧
  188.          */
  189.         protected $_tagStatus = array();
  190.         /**
  191.          * 標(biāo)簽棧
  192.          */
  193.         protected $_tagStack = array();
  194.         /**
  195.          * 當(dāng)前標(biāo)簽名稱
  196.          */
  197.         protected $_tagName = '';
  198.        
  199.         /**
  200.          * 標(biāo)簽開始標(biāo)識(shí)
  201.          */
  202.         const TAG_START = 10;
  203.         /**
  204.          * 標(biāo)簽結(jié)束標(biāo)識(shí)
  205.          */
  206.         const TAG_END   = 20;

  207.         /**
  208.          * 標(biāo)簽名字開始
  209.          */
  210.         const TAGNAME_START = 30;
  211.         /**
  212.          * 標(biāo)簽名字結(jié)束
  213.          */
  214.         const TAGNAME_END = 40;
  215.         /**
  216.          * 注釋開始(保留)
  217.          */
  218.         const COMMENT_START = 50;
  219.         /**
  220.          * 注釋結(jié)束(保留)
  221.          */
  222.         const COMMENT_END = 60;


  223.         /**
  224.          *  事件回調(diào)對(duì)象
  225.          */
  226.         public $_elementHandler = null;
  227.         /**
  228.          *
  229.          * 構(gòu)函方法
  230.          * @param striing $html 要解析的字符串
  231.          * @param object|array elementHandler 回調(diào)處理器可以是數(shù)組也可以是對(duì)象
  232.          *                對(duì)象只要實(shí)現(xiàn)相同的方法名就可以,注意這里沒有用到接口
  233.                         如果是數(shù)組,方法名作為下標(biāo)即可
  234.          *
  235.          */
  236.         public function htmlParse($html,$elementHander=null)
  237.         {
  238.                 $this->setHtml($html);
  239.                 $this->setElementHandler($elementHander);
  240.         }
  241.         /**
  242.          *
  243.          * 重新設(shè)定要解析的內(nèi)容
  244.          * @param string $html
  245.          *
  246.          */
  247.         public function setHtml($html)
  248.         {
  249.                 $this->_html = $html;
  250.                 $this->_reset();
  251.         }
  252.         /**
  253.          *
  254.          * 重位處理指針,要處理的字符長度
  255.          *
  256.          */
  257.         public function _reset()
  258.         {
  259.                 $this->_pt = 0;
  260.                 $this->_htmlLength = strlen($this->_html);
  261.         }
  262.         /**
  263.          * 重新指定處理器
  264.          * @param object|array elementHandler
  265.          */
  266.         public function setElementHandler($elementHander)
  267.         {
  268.                 $this->_elementHandler = $elementHander;
  269.         }
  270.         /**
  271.          * 獲取要處理的下一個(gè)字符 指針自動(dòng)后移
  272.          * 到結(jié)尾了返回false
  273.          * @return char
  274.          */
  275.         public function nextChar()
  276.         {
  277.                 if ($this->_pt < $this->_htmlLength){
  278.                         return $this->_html[$this->_pt++];
  279.                 }
  280.                
  281.                 return false;
  282.         }
  283.         /**
  284.          * 獲取處理過的上一個(gè)字符指針回退
  285.          * 到結(jié)尾了返回false
  286.          * @return char
  287.          */
  288.         public function preChar()
  289.         {
  290.                 if ($this->_pt > 0){
  291.                         return $this->_html[--$this->_pt];
  292.                 }
  293.                 return false;
  294.         }
  295.         /**
  296.          * 獲得當(dāng)前處理位置
  297.          * @return integer
  298.          */
  299.         public function getPt()
  300.         {
  301.                 return $this->_pt;
  302.         }
  303.         /**
  304.          * 設(shè)置處理位置 成功返回true 失敗false
  305.          * @return bool
  306.          */
  307.         public function setPt($v)
  308.         {
  309.                 if ($v>-1 && $v < $this->_htmlLength){
  310.                         $this->_pt = $v;
  311.                         return true;
  312.                 }
  313.                 return false;
  314.         }

  315.         public function addTagStack()
  316.         {
  317.                 return array_push($this->_tagStack,$this->_tagName);
  318.         }

  319.         public function startElement($parse,$tagName)
  320.         {
  321.         }

  322.         public function endElement($parse,$tagName)
  323.         {
  324.         }
  325.         public function characterData($parse,$char)
  326.         {
  327.         }

  328.         public function endParse($parse)
  329.         {
  330.         }

  331.         public function callHandler($callback)
  332.         {
  333.                 $argv = func_get_args();
  334.                 array_shift($argv);
  335.                 array_unshift($argv,$this);
  336.                 if (is_array($this->_elementHandler) && $this->_elementHandler[$callback]){
  337.                         return call_user_func_array($this->_elementHandler[$callback],$argv);

  338.                 }else{
  339.                         $handler = is_object($this->_elementHandler) ? $this->_elementHandler : $this;
  340.                         if (method_exists($handler,$callback)){
  341.                                 return call_user_method_array($callback,$handler,$argv);
  342.                         }
  343.                 }
  344.         }

  345.         public function parse()
  346.         {
  347.                 while(($char=$this->nextChar()) !== false)
  348.                 {
  349.                         switch($char)
  350.                         {
  351.                                 case '<':
  352.                                         if (!$this->_tagStatus || end($this->_tagStatus) == self::TAG_END)       
  353.                                         {
  354.                                                 $pt = $this->getPt();

  355.                                                 $char1 = $this->nextChar();
  356.                                                 $char2 = $this->nextChar();
  357.                                                 $char3 = $this->nextChar();
  358.                                                 $refor = false;
  359.                                                 if ($char1 == '!' && ($char2 == '-' && $char3 == '-')) {
  360.                                                         //如果是注釋
  361.                                                         while(($char1=$this->nextChar()) !== false)
  362.                                                         {
  363.                                                                
  364.                                                                 if ($char1 != '>') continue;
  365.                                                                 $pt2 = $this->getPt();
  366.                                                                 $this->preChar();
  367.                                                                 $char2 = $this->preChar();
  368.                                                                 $char3 = $this->preChar();
  369.                                                                 if ($char2 == '-' && $char3 == '-') {

  370.                                                                         $refor = true;
  371.                                                                         $this->setPt($pt2);
  372.                                                                         break;
  373.                                                                 }
  374.                                                                 $this->setPt($pt2);
  375.                                                         }
  376.                                                        
  377.                                                 }
  378.                                                 if ($refor){
  379.                                                         continue;
  380.                                                 }

  381.                                                 $this->setPt($pt);
  382.        
  383.                                                 array_push($this->_tagStatus,self::TAG_START);
  384.                                                 array_push($this->_tagStatus,self::TAGNAME_START);
  385.                                                 $this->_tagName = '';
  386.                                         }
  387.                                 break;
  388.                                 case ' ':  case '>':
  389.                                         if (!$this->_tagStatus || end($this->_tagStatus) == self::TAG_END){
  390.                                                 $callback = 'characterData';
  391.                                                 $this->callHandler($callback,$char);
  392.                                                 continue;
  393.                                         }
  394.                                         $callback = '';
  395.                                         if (end($this->_tagStatus) == self::TAGNAME_START) {
  396.                                                 array_pop($this->_tagStatus);
  397.                                                 array_push($this->_tagStatus , self::TAGNAME_END);
  398.                                                 if ($this->_tagName[0] == '/'){
  399.                                                         $this->_tagName = substr($this->_tagName,1);
  400.                                                         $callback = 'endElement';
  401.                                                 }else{
  402.                                                         $callback = 'startElement';
  403.                                                 }
  404.                                         }
  405.                                         // <p /> <p/> <p / >
  406.                                         // <link ... />
  407.                                         if (in_array(end($this->_tagStatus) ,array(self::TAGNAME_START,        self::TAGNAME_END)) && $char == '>'){
  408.                                                 $pt = $this->getPt();
  409.                                                 $this->setPt($pt-1);
  410.                                                 while(($char2=$this->preChar()) !== false && !preg_match("#\s#",$char2)){
  411.                                                         if ($char2 == '/'){
  412.                                                                 //自閉合標(biāo)簽
  413.                                                                 $callback = 'endElement';
  414.                                                                 array_pop($this->_tagStatus); //end tagname_start
  415.                                                                 array_push($this->_tagStatus , self::TAGNAME_END);
  416.                                                         }
  417.                                                         break;
  418.                                                 }
  419.                                                 $this->setPt($pt);
  420.                                         }
  421.                                         if ($callback == 'startElement'){
  422.                                                 $this->addTagStack();
  423.                                                 $this->callHandler($callback,$this->_tagName);
  424.                                         }elseif ($callback == 'endElement'){

  425.                                                 array_pop($this->_tagStatus); //end tagname
  426.                                                 array_pop($this->_tagStatus); // end tag
  427.                                                 $this->callHandler($callback,$this->_tagName);
  428.                                         }
  429.                                         if (end($this->_tagStatus) == self::TAGNAME_END && $char == '>'){
  430.                                                 array_pop($this->_tagStatus); //end tag name
  431.                                                 array_pop($this->_tagStatus); //end tag
  432.                                         }
  433.                                 break;
  434.                                 default:
  435.                                         if (end($this->_tagStatus) == self::TAGNAME_START)
  436.                                         {
  437.                                                 $this->_tagName .= $char;
  438.                                         }
  439.                                         if (!$this->_tagStatus || end($this->_tagStatus) == self::TAG_END){
  440.                                                 $callback = 'characterData';
  441.                                                 $this->callHandler($callback,$char);
  442.                                         }
  443.                                 break;
  444.                         }
  445.                 }
  446.                 $callback = 'endParse';
  447.                 $this->callHandler($callback,$char);
  448.         }
  449. }
  450. /**
  451. */
  452. class htmlTag
  453. {
  454.         public $tagName = '';
  455.         public $type = '';
  456.         public $depth = 0;
  457.         public $parent = null;
  458.         public $childs = array();

  459.         public $textLength = 0;

  460.         public $tagNum  = 0;
  461.         public $textNum = 0;

  462.         const DOM_TAG = 1;

  463.         public function __construct($tagName,$type)
  464.         {
  465.                 $this->type = $type;
  466.                 $this->tagName = $tagName;
  467.         }

  468.         public function addChild($child)
  469.         {
  470.                 array_push($this->childs,$child);
  471.                 if (!is_object($child)){
  472.                         $this->textLength += $this->_strlen($child,true);
  473.                         $this->textNum++;
  474.                 }else{
  475.                         $this->tagNum++;
  476.                 }
  477.         }
  478.         public function _strlen($text,$ignoreSpace=false)
  479.         {
  480.                 if ($ignoreSpace) $text = preg_replace("#\s*#s","",$text);
  481.                 return strlen($text);
  482.         }

  483.         public function getChildren()
  484.         {
  485.                 $result = array();
  486.                 foreach($this->childs as $dom)
  487.                 {
  488.                         $result[] = $dom;
  489.                 }
  490.                 return $result;
  491.                
  492.         }
  493.         public function getText()
  494.         {
  495.                 $text = '';
  496.                 foreach($this->childs as $dom){
  497.                         if (is_string($dom)) $text .= $dom;
  498.                 }
  499.                 return $text;
  500.         }
  501. }

  502. class htmlExtractorHandler
  503. {
  504.         public $ignoreTags=array(
  505.                 "!doctype","meta","link","hr","!--","base","basefont","br",
  506.                 "frame","frameset","noframes","iframe",
  507.                 "input","button","select","optgroup","option",
  508.                 "label","fieldset","legend","isindex",
  509.                 "img","map","area","style",
  510.                 "script","noscript","applet","object","param","marquee","embed");

  511.         protected $_dom = array();

  512.         private $_charBuffer = '';
  513.         private $_domDepth   = 0;

  514.         public function __construct($root)
  515.         {
  516.                 array_push($this->_dom,$root);
  517.         }

  518.         public function isIgnore($tag)
  519.         {
  520.                 $tag = strtolower($tag);
  521.                 return in_array($tag,$this->ignoreTags);
  522.         }

  523.         public function endParse()
  524.         {
  525.                 $this->updateChacter();
  526.         }

  527.         public function updateChacter()
  528.         {
  529.                 if ($this->_charBuffer != ''){
  530.                         end($this->_dom)->addChild($this->_charBuffer);
  531.                         $this->_charBuffer = '';
  532.                 }
  533.         }

  534.         public function startElement($parse,$tagName)
  535.         {
  536.                 $this->updateChacter();
  537.                 $tagName = strtolower($tagName);
  538.                 if ($this->isIgnore($tagName) === true) return false;

  539.                 $dom = new htmlTag($tagName,htmlTag::DOM_TAG);
  540.                 $parent = end($this->_dom);
  541.                 $dom->parent = $parent;
  542.                 //echo str_repeat("    ",$this->_domDepth)."[{$dom->tagName}_{$this->_domDepth}]\r\n";
  543.                 $dom->depth  = ++$this->_domDepth;
  544.                 $parent->addChild($dom);
  545.                

  546.                 array_push($this->_dom,$dom);
  547.         }

  548.         public function endElement($parse,$tagName)
  549.         {
  550.                 $this->updateChacter();
  551.                 $tagName = strtolower($tagName);
  552.                 if ($this->isIgnore($tagName) === true) return false;
  553.                 $dom = end($this->_dom);
  554.                 if (end($this->_dom)->tagName == $tagName) {
  555.                         array_pop($this->_dom);
  556.                         $this->_domDepth--;
  557.                 }
  558.                 //echo str_repeat("    ",$this->_domDepth)."[/{$dom->tagName}_{$this->_domDepth}]\r\n";
  559.         }
  560.         public function characterData($parse,$char)
  561.         {
  562.                 $this->_charBuffer .= $char;
  563.         }
  564. }
復(fù)制代碼
把代碼當(dāng)附件也放一份上來吧
html-extractor.php.zip (5.51 KB, 下載次數(shù): 137)




歡迎光臨 Chinaunix (http://72891.cn/) Powered by Discuz! X3.2