为什么80%的码农都做不了架构师?>>>   hot3.png

<?php

/// 如何利用栈将html解析成节点树
/// 首先html是由一个个节点组成,最大的节点为<html></html>节点   她有两个子节点<head></head> 和<body></body>
/// 首先我们将<html>压入栈中 再将<head>压入栈中 遇到</head>出栈  <body>压入栈中 遇到</body> 出栈 最终<html>
/// 出栈 可以看出 出栈的一定是栈顶元素的子节点
/// 本程序假定html完全规范

/// todo  解决标签未闭合问题
/// todo  根据标签名访问
///       根据id访问
///       根据class访问
///      innerHtml 和 innerText

$tree_file = fopen("tree_file","w");
fclose($tree_file);

$siteurl="http://www.cnblogs.com/poissonnotes/archive/2010/05/28/1745996.html";
$str=get_content_by_url($siteurl);

$pattern="/<.*?>/";
$deep=0;

$global_false=true ;

$result=array();

$queue_id=0;

if(preg_match_all($pattern,$str,$matches))
{    
    $count=count($matches[0]);
    $matches=$matches[0];
    $queue=array();
    $error = fopen("string_tagss","a");
    
    for($i=0;$i<$count;$i++)
    {
        $temptag = $matches[$i];
        
        $node["Id"]=$i;
        $node["ChildId"]=array();
        $node["html_tag"]=$temptag;
        /// 如果是单标签
        if(is_single_tag($temptag))
        {
            //echo "this is a single tag:    ";
            //echo $temptag."\n";
            $str_deep=make_string($deep);
            fwrite($error,$str_deep."\t".$temptag."\n");

if(!empty($queue))
            {
                $queue[count($queue)-1]["ChildId"][]=$queue_id;
            }
            $queue_id++;
            $result[]=$node;
            continue ;
        }
    
        /// 如果是结束标签
        if(is_end_tag($temptag))
        {    
            $temp_node = array_pop($queue);
            $queue[count($queue)-1]["ChildId"][]=$queue_id ;  // 出队的节点一定是栈顶元素的子孩子
            $queue_id++;
            $result[]=$temp_node;
        }
        else
        {    
            /// 如果是开始标签     
            $str_deep=make_string($deep);
            fwrite($error,$str_deep."\t".$temptag."\n");
            $queue[] = $node;
            $deep++;
        }
    }

if($global_false)
    {
        echo "ok\n" ;
    }
    else
    {
        echo "error\n" ;
    }
        
    //制作关系图谱  不包含结束标签
    //<html>
    //    <head>
    //            ............
    //        ............
    //    <body>
    //              ............
        //              ............

$deep = 0;
    make_tree($result,$result[count($result)-1],$deep);

}

function is_single_tag($test_tag)
{
    $single_tags=array("meta","img","link","input","!DOCTYPE","area","base","basefont","embed","hr","br");
    $single_tag_string="(";
    foreach($single_tags as $single_tag)
    {
        $single_tag_string=$single_tag_string.$single_tag."|"  ;
    }
    $single_tag_string=$single_tag_string.")";
    $single_tag_string=str_replace("|)",")",$single_tag_string);
    $pattern="/\<".$single_tag_string.".*?\>/ i" ;
    
    if(preg_match($pattern,$test_tag))
    {
        return true ;
    }

return false ;
}

function is_end_tag($test_tag)
{
    $pattern="/\<\/.*?\>/" ;
    if(preg_match($pattern,$test_tag))
    {
        return true ;
    }    
    return false ;
}

function is_exist_start_tag($queue,$temptag)
{
    $end_string=str_replace("/","",$temptag);
    $end_string=preg_replace("/\s*/","",$end_string);
    $end_string=strtolower($end_string);
    
    $count=count($queue);

echo $count."\n";

var_dump($queue);    
    
    for($i=$count-1;$i>=0;$i--)
    {    
        
        echo $i."\n";
        $string = $queue[$i]["html_tag"];        
        $string = preg_replace("/(<)(.*?)\s.*?(>)/",'$1$2$3',$string);    
        if(strtolower($string) == strtolower($end_string))
        {
            return true;
        }
    }        
    return false ;
}

function is_pear_tag($start_tag,$temptag)
{    
    $start_string=preg_replace("/(<)(.*?)\s.*?(>)/",'$1$2$3',$start_tag);    
    $end_string=str_replace("/","",$temptag);
    $end_string=preg_replace("/\s*/","",$end_string);    
    if(strtolower($start_string) == strtolower($end_string))
    {
        return true ;
    }
    else
    {
        return false ;
    }
}

function make_string($deep)
{
    $temstr="";
    for($i=0;$i<$deep;$i++)
        $temstr=$temstr."-";
    return $temstr;
}

function judge_tag($last_tag,$temptag)
{
    return false;
// 这里做一个判断 判断上一个标签是否能嵌套这个标签 比如
// <td> 不嵌套<td>
// <td> 不嵌套<tr>
// <tr> 不嵌套<tr>
// <tr> 不嵌套<table>   
// <table> 嵌套  <tr>  但不能嵌套其他 标签  
// <li> 不嵌套<li>
// <ul> 不嵌套<ul>
// <ol> 不嵌套<ol>    
// <head> 不能嵌套 <body>
}

function get_content_by_url($site_url)
{
    $ch=curl_init($site_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch, CURLOPT_ENCODING, "gzip");
    $content=curl_exec($ch);
    $content = str_replace("\r\n","",$content);
    $content = str_replace("\n\r","",$content);
    $content = str_replace("\n","",$content);
    $content = str_replace("\r","",$content);
    $content = preg_replace("/<!--\[if.*?<!\[endif\]-->/is","",$content);
    $content = preg_replace("/<!--.*?-->/is","",$content);
    $content = preg_replace("/<script(.*?)<\/script>/is","",$content);  
    $content = preg_replace("/<style(.*?)<\/style>/is","",$content);

$errores = fopen("baidu","w");
    fwrite($errores,$content) ;
    fclose($errores);
    
    return $content ;
}

function make_tree($result,$node,$deep)
{
    // 制作前缀 使得显示的层次分明
    $str="" ;
    for($i=0;$i<$deep;$i++)
    {
        $str=$str."--";    
    }
    echo $str;
    echo $node["html_tag"]."\n";

$write_str = $str.$node["html_tag"]."\n";
    
    $tree_file = fopen("tree_file","a");
    fwrite($tree_file,$write_str);
    fclose($tree_file);

$deep++;

if(!empty($node["ChildId"]))
    {
        foreach($node["ChildId"] as $Child)
        {
            make_tree($result,$result[$Child],$deep) ;   ///递归
        }
    }
    else
    {
        return ;
    }
}
?>

转载于:https://my.oschina.net/qidis/blog/535004

利用栈将html源码解析为节点树相关推荐

  1. 栈解析html文件,利用栈将html源码解析为节点树

    /// 如何利用栈将html解析成节点树 /// 首先html是由一个个节点组成,最大的节点为节点   她有两个子节点 和 /// 首先我们将压入栈中 再将 压入栈中 遇到出栈  压入栈中 遇到 出栈 ...

  2. btcd源码解析——peer节点之间的区块数据同步 (3) —— 非headersFirstMode模式

    文章目录 1. 写在前面 2. 非headersFirstMode模式下的数据同步过程 2.1 peer A 发送"获取区块哈希"的请求 2.2 peer B 响应"获取 ...

  3. Fabric v2.0 源码解析——排序节点(Orderer)运行机制

    本文的内容还需进一步丰富,有时间会继续完善. 文章目录 1. Orderer在Fabric网络中的作用 Handle函数 2. Orderer接收的交易类型 ProcessMessage函数 3. 共 ...

  4. Vue2源码解析 虚拟节点VNode

    目录 1  什么是VNode 2  VNode的作用 3  VNode的类型 3.1  注释节点 3.2  文本节点 3.3  克隆节点 3.4  元素节点 3.5  组件节点 3.6  函数式组件 ...

  5. zookeeper源码解析--从节点

    概述 从节点参与选举,选举结束,自身不为主,自动成为集群从节点. 从节点,一方面作为集群主节点的从节点,与其交互. 一方面,从节点可以作为集群观察者的主节点,与观察者交互. 与主交互 主干逻辑–fol ...

  6. Android技术栈--HashMap和ArrayMap源码解析

    1 总览 WARNING!!:本文字数较多,内容较为完整并且部分内容难度较大,阅读本文需要较长时间,建议读者分段并耐心阅读. 本文会对 Android 中常用的数据结构进行源码解析,包括 HashMa ...

  7. Android技术栈(五)HashMap(包括红黑树)与ArrayMap源码解析

    1 总览 本文会对 Android 中常用HashMap(有红黑树)和ArrayMap进行源码解析,其中 HashMap 源码来自 Android Framework API 28 (JDK=1.8) ...

  8. python flask源码解析_用尽洪荒之力学习Flask源码

    [TOC] 一直想做源码阅读这件事,总感觉难度太高时间太少,可望不可见.最近正好时间充裕,决定试试做一下,并记录一下学习心得. 首先说明一下,本文研究的Flask版本是0.12. 首先做个小示例,在p ...

  9. shiro反序列化工具_Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)源码解析

    Apache Shiro Apache Shiro是一个功能强大且灵活的开源安全框架,主要功能包括用户认证.授权.会话管理以及加密.在了解该漏洞之前,建议学习下Apache Shiro是怎么使用. d ...

  10. 【Vue.js源码解析 一】-- 响应式原理

    前言 笔记来源:拉勾教育 大前端高薪训练营 阅读建议:建议通过左侧导航栏进行阅读 课程目标 Vue.js 的静态成员和实例成员初始化过程 首次渲染的过程 数据响应式原理 – 最核心的特性之一 准备工作 ...

最新文章

  1. 一分钟学会看k线图_看K线图:阴跌如钝刀
  2. APP性能之终端兼容
  3. Ancient China Story of Shen-《Kung Fu Panda 2》
  4. 计算机网络技术发源于什么,计算机网络基础试题和答案
  5. 监听列表ListVIew的滑动状态
  6. CSS实现半透明div层的方法
  7. 华为可以看游戏时长吗_怎么测试华为手机玩游戏的帧率情况
  8. python优雅编程_Python优雅编程——Collections模块中的高性能数据类型
  9. python和pycharm怎么安装_Python3和PyCharm安装与环境配置【图文教程】
  10. 结构型设计模式 (1)—— 适配器模式(Adapter Pattern)
  11. 液压系统管路流速推荐表_(整理)液压系统油管选择.
  12. C++ 类图 Astah画类图
  13. sketch 3.8.1(破解版涵盖3.0,3.7,3.8.0以上版本) 安装and使用指南(20160524)更新)
  14. Word设置默认粘贴格式,自动更改粘贴格式
  15. 影片剪辑app android,猫饼剪辑app
  16. 使用Travis CI进行在线build
  17. Vue - 生成二维码(把链接地址或字符文字转成二维码,扫描后可打开显示)
  18. STP生成树协议(超详细小白也能看懂)
  19. b ,B,KB,MB,GB之间的关系
  20. 在Layui框架里设计一个评论列表的前端界面

热门文章

  1. 动态规划入门之最长公共子序列
  2. 海量数据挖掘MMDS week6: MapReduce算法(进阶)
  3. Django项目实践1 - 创建Django项目
  4. C语言中的system函数参数详解
  5. React + leaflet 地图瓦片 加载错乱 不能正常显示
  6. 十种日常食物比砒霜还毒!
  7. 思科路由器RIP路由汇总
  8. matlab钢材切割,一种基于MATLAB的钢材裂纹扩展速率试验数据处理方法
  9. 游戏开发之nullptr和的NULL的区别(C++基础)
  10. HCIE Security 2020.12.04面试战报