利用栈将html源码解析为节点树
为什么80%的码农都做不了架构师?>>>
<?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源码解析为节点树相关推荐
- 栈解析html文件,利用栈将html源码解析为节点树
/// 如何利用栈将html解析成节点树 /// 首先html是由一个个节点组成,最大的节点为节点 她有两个子节点 和 /// 首先我们将压入栈中 再将 压入栈中 遇到出栈 压入栈中 遇到 出栈 ...
- btcd源码解析——peer节点之间的区块数据同步 (3) —— 非headersFirstMode模式
文章目录 1. 写在前面 2. 非headersFirstMode模式下的数据同步过程 2.1 peer A 发送"获取区块哈希"的请求 2.2 peer B 响应"获取 ...
- Fabric v2.0 源码解析——排序节点(Orderer)运行机制
本文的内容还需进一步丰富,有时间会继续完善. 文章目录 1. Orderer在Fabric网络中的作用 Handle函数 2. Orderer接收的交易类型 ProcessMessage函数 3. 共 ...
- Vue2源码解析 虚拟节点VNode
目录 1 什么是VNode 2 VNode的作用 3 VNode的类型 3.1 注释节点 3.2 文本节点 3.3 克隆节点 3.4 元素节点 3.5 组件节点 3.6 函数式组件 ...
- zookeeper源码解析--从节点
概述 从节点参与选举,选举结束,自身不为主,自动成为集群从节点. 从节点,一方面作为集群主节点的从节点,与其交互. 一方面,从节点可以作为集群观察者的主节点,与观察者交互. 与主交互 主干逻辑–fol ...
- Android技术栈--HashMap和ArrayMap源码解析
1 总览 WARNING!!:本文字数较多,内容较为完整并且部分内容难度较大,阅读本文需要较长时间,建议读者分段并耐心阅读. 本文会对 Android 中常用的数据结构进行源码解析,包括 HashMa ...
- Android技术栈(五)HashMap(包括红黑树)与ArrayMap源码解析
1 总览 本文会对 Android 中常用HashMap(有红黑树)和ArrayMap进行源码解析,其中 HashMap 源码来自 Android Framework API 28 (JDK=1.8) ...
- python flask源码解析_用尽洪荒之力学习Flask源码
[TOC] 一直想做源码阅读这件事,总感觉难度太高时间太少,可望不可见.最近正好时间充裕,决定试试做一下,并记录一下学习心得. 首先说明一下,本文研究的Flask版本是0.12. 首先做个小示例,在p ...
- shiro反序列化工具_Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)源码解析
Apache Shiro Apache Shiro是一个功能强大且灵活的开源安全框架,主要功能包括用户认证.授权.会话管理以及加密.在了解该漏洞之前,建议学习下Apache Shiro是怎么使用. d ...
- 【Vue.js源码解析 一】-- 响应式原理
前言 笔记来源:拉勾教育 大前端高薪训练营 阅读建议:建议通过左侧导航栏进行阅读 课程目标 Vue.js 的静态成员和实例成员初始化过程 首次渲染的过程 数据响应式原理 – 最核心的特性之一 准备工作 ...
最新文章
- 一分钟学会看k线图_看K线图:阴跌如钝刀
- APP性能之终端兼容
- Ancient China Story of Shen-《Kung Fu Panda 2》
- 计算机网络技术发源于什么,计算机网络基础试题和答案
- 监听列表ListVIew的滑动状态
- CSS实现半透明div层的方法
- 华为可以看游戏时长吗_怎么测试华为手机玩游戏的帧率情况
- python优雅编程_Python优雅编程——Collections模块中的高性能数据类型
- python和pycharm怎么安装_Python3和PyCharm安装与环境配置【图文教程】
- 结构型设计模式 (1)—— 适配器模式(Adapter Pattern)
- 液压系统管路流速推荐表_(整理)液压系统油管选择.
- C++ 类图 Astah画类图
- sketch 3.8.1(破解版涵盖3.0,3.7,3.8.0以上版本) 安装and使用指南(20160524)更新)
- Word设置默认粘贴格式,自动更改粘贴格式
- 影片剪辑app android,猫饼剪辑app
- 使用Travis CI进行在线build
- Vue - 生成二维码(把链接地址或字符文字转成二维码,扫描后可打开显示)
- STP生成树协议(超详细小白也能看懂)
- b ,B,KB,MB,GB之间的关系
- 在Layui框架里设计一个评论列表的前端界面