爬虫逆向你应该懂得Javascript知识

背景

大家在学习爬虫逆向的时候,一般都会涉及到对js源文件进行代码扣去,但是有的时候,你最好有js基础,能发现加密或者解密在那个位置,或者是能用python改写js代码,这就对个人的Javascript的能力有一定要求,用了一段时间给大家整理出来了。
本篇文章整理源:https://blog.csdn.net/qq_38490457/article/details/109257751 ,本人只把js逆向应该懂得语法写了出来,如果大家有什么不明白的,可以去 看一下原作者。

js逆向技巧

​ 调用函数时,解析器也不会检查实参的数量,多余实参不会被赋值,如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined。

​ chunk开头的js文件是 vue打包后的。

webpack整合后的js文件一般带有webpack_require等字段。

立即执行函数:
(function () {
    alert("我是一个匿名函数");
})();

concat()

连接数组,使数组增长

var arr = ["孙悟空", "猪八戒", "沙和尚"];
var arr2 = ["白骨精", "玉兔精", "蜘蛛精"];
var arr3 = ["二郎神", "太上老君", "玉皇大帝"];
var result = arr.concat(arr2, arr3, "牛魔王", "铁扇公主");
console.log(result);
 
join():

数组连接符,间隔符

var arr = ["孙悟空", "猪八戒", "沙和尚"];
var result = arr.join("@-@");
console.log(result);
call和apply:

call(对象,参数) apply(对象,参数)

person.sayHello.call(person, "Hello");  // 输出:Hello, John
person.sayHello.apply(person, ["Hello"]);  // 输出:Hello, John
Date:
var date = new Date();
console.log(date);
console.log(date.getFullYear());//获取当前日期对象的年份(四位数字年份)
console.log(date.getMonth());//获取当前日期对象的月份(0 ~ 11)
console.log(date.getDate());//获取当前日期对象的日数(1 ~ 31)
console.log(date.getHours());//获取当前日期对象的小时(0 ~ 23)
console.log(date.getMinutes());//获取当前日期对象的分钟(0 ~ 59)
console.log(date.getSeconds());//获取当前日期对象的秒钟(0 ~ 59)
console.log(date.getMilliseconds());//获取当前日期对象的毫秒(0 ~ 999)
随机数:
/*随机数*/
//Math.random():可以用来生成一个0-1之间的随机数
//生成一个0-x之间的随机数:Math.round(Math.random()*x)
//生成一个x-y之间的随机数:Math.round(Math.random()*(y-x)+x)
console.log(Math.round(Math.random() * 10));            //生成一个0-10之间的随机数
console.log(Math.round(Math.random() * (10 - 1) + 1));  //生成一个1-10之间的随机数

字符串操操作:
concat

字符串连接concat

var str = "Hello,World!";
console.log(str.concat("你好,", "世界!"));

slice:
  • 第一个参数:开始位置的索引(包括开始位置)
  • 第二个参数:结束位置的索引(不包括结束位置),如果省略第二个参数,则会截取到后边所有的
var str = "Hello,World!";
var result = str.slice(1, 4);
console.log(result);
result = str.slice(1);
console.log(result);
result = str.slice(1, -1);
console.log(result);
substr

子串:参数:

  • 第一个参数:截取开始位置的索引
  • 第二个参数:截取的长度
var str = "Hello,World!";
var result = str.substr(6, 6);
console.log(result);

split

字符串拆分:

该方法可以将一个字符串拆分为一个数组,需要一个字符串作为参数,将会根据该字符串去拆分数组

var str = "Hello,World!";
var result = str.split(",");
console.log(result);

字符串大小写转化:

var str = "Hello,World!";
var result = str.toUpperCase();
var result = str.toLowerCase();
正则:

创建方式一:

var 变量名 = new RegExp(“正则表达式”,“匹配模式”);

匹配模式:

  • i:忽略大小写
  • g:全局匹配模式
  • ig:忽略大小写且全局匹配模式
// 这个正则表达式可以来检查一个字符串中是否含有a
var reg = new RegExp("ab", "i");
var str = "Abc";
var result = reg.test(str);
console.log(result);

创建方式二:

var 变量名 = /正则表达式/匹配模式;

匹配模式:

  • i:忽略大小写

  • g:全局匹配模式

  • m:执行多行匹配

  • [a-z]:任意小写字母

  • [A-Z]:任意大写字母

  • [A-z]:任意字母

  • [0-9]:任意数字

search() 返回第一个出现的位置,没有则返回-1

match() 找到第一个符合要求的内容,设置匹配模式为 g ,可以将所有的匹配出来

replace( ) 默认只会替换第一个 设置全局匹配替换全部

var result = str.search(/a[bef]c/);
var result = str.match(/[a-z]/ig);
var result = str.replace(/[a-z]/gi, "@_@");

正则量词:

  • {n} :正好出现n次

  • {m,} :出现m次及以上

  • {m,n} :出现m-n次

  • + :至少一个,相当于{1,}

  • * :0个或多个,相当于{0,}

  • ? :0个或1个,相当于{0,1}

  • ^ :表示开头,注意它在[^字符序列]表达的意思不一样

  • $ :表示结尾

  • [^a-z]:除了任意小写字母

  • [^A-Z]:除了任意大写字母

  • [^A-z]:除了任意字母

  • [^0-9]:除了任意数字

转义字符:

  • \. :表示.
  • \\ :表示\

泛指:

  • \w :任意字母、数字、,相当于[A-z0-9]
  • \W :除了字母、数字、,相当于[^A-z0-9]
  • \d :任意的数字,相当于[0-9]
  • \D :除了任意的数字,相当于[^0-9]
  • \s :空格
  • \S :除了空格
  • \b :单词边界
  • \B :除了单词边界
案例:

除去空格:

var str = "  hello xxxxx  "
var reg = /^\s*|\s*$/g;
console.log(str);
str = str.replace(reg, "");
console.log(str);

检验单词:

var str = "hello child"
var reg = /\bchild\b/;
console.log(reg.test(str));

检测手机号:

var phoneStr = "15131494600";
var phoneReg = /^1[3-9][0-9]{9}$/;
console.log(phoneReg.test(phoneStr));
DOM节点

获取标签:

  • getElementById()
  • getElementsByTagName()
  • getElementsByClassName()
  • querySelector( ) css选择器
  • querySelectorAll(" ")

获取值:

​ 方法 描述
元素节点.innerText 获取 HTML 元素的 inner Text。
元素节点.innerHTML 获取 HTML 元素的 inner HTML。
元素节点.属性 获取 HTML 元素的属性值。 a.href
元素节点.getAttribute(attribute) 获取 HTML 元素的属性值。 a.getAttribute(“href”)

元素节点.setAttribute(attribute, value) 改变 HTML 元素的属性值。

元素节点.style.样式 获取 HTML 元素的行内样式值。

<script>
    var box = document.getElementById("box");
    console.log(box.style.width);
</script>
<script>
    /*通用的获取元素样式的方法*/
    function getStyle(obj, name) {
        if (window.getComputedStyle) {
            //正常浏览器的方式,具有getComputedStyle()方法
            return getComputedStyle(obj, null)[name];
        } else {
            //IE8的方式,没有getComputedStyle()方法
            return obj.currentStyle[name];
        }
    }

    var box = document.getElementById("box");

    console.log(getStyle(box, "width"));
    console.log(getStyle(box, "height"));
    console.log(getStyle(box, "background-color"));
</script>
//编写一段兼容性代码,用来获取任意标签的文本内容
<script>
    var a = document.getElementById("a");

    console.log(getInnerText(a));

    /*获取任意标签的内容*/
    function getInnerText(element) {
        // 判断浏览器是否支持textContent,如果支持,则使用textContent获取内容,否则使用innerText获取内容。
        if(typeof element.textContent == "undefined") {
            return element.innerText;
        } else {
            return element.textContent;
        }
    }
</script>

修改 HTML 元素

方法 描述
document.createElement(element) 创建 HTML 元素节点。
document.createAttribute(attribute) 创建 HTML 属性节点。
document.createTextNode(text) 创建 HTML 文本节点。
元素节点.removeChild(element) 删除 HTML 元素。
元素节点.appendChild(element) 添加 HTML 元素。
元素节点.replaceChild(element) 替换 HTML 元素。
元素节点.insertBefore(element) 在指定的子节点前面插入新的子节点。

DOM事件

窗口事件:

属性描述
onblur当窗口失去焦点时运行脚本
onfocus当窗口获得焦点时运行脚本。
onload当文档加载之后运行脚本。
onresize当调整窗口大小时运行脚本
onstorage当 Web Storage 区域更新时(存储空间中的数据发生变化时)运行脚本。
<script>
    window.onblur = function () {
        console.log("窗口失去焦点");
    };
</script>
<script>
    window.onfocus = function () {
        console.log("窗口获取焦点");
    };
</script>

表单事件:

属性描述
onblur当元素失去焦点时运行脚本
onfocus当元素获得焦点时运行脚本。
onchange当元素改变时运行脚本。
oninput当元素获得用户输入时运行脚本。
oninvalid当元素无效时运行脚本。
onselect当选取元素时运行脚本。
onsubmit当提交表单时运行脚本。
<script>
    var textInput = document.getElementById("text");
/* 当文本框获取焦点,文本框背景为红色 */
textInput.onfocus = function () {
    this.style.background = "red";
};

/* 当文本框失去焦点,文本框背景为绿色 */
textInput.onblur = function () {
    this.style.background = "green";
};

this就是调用者,谁调用就是谁。

BOM事件

就是 broswer object model 浏览器对象,浏览器自带的对象有 window,navigate,loaction,history,screen ,这个地方很重要,为什么需要补环境,因为我们的使用nodejs模拟浏览器执行js,但是node的环境是没有这些对象的。

Window对象

警告框

window.alert("sometext");
alert("sometext");

确认框

window.confirm("sometext");
confirm("sometext");

如果您希望用户验证或接受某个东西,则通常使用“确认”框。

当确认框弹出时,用户将不得不单击“确定”或“取消”来继续进行。

如果用户单击“确定”,该框返回 true。如果用户单击“取消”,该框返回 false。

提示框

window.prompt("sometext","defaultText");// sometext提示词 default默认值

如果用户单击“确定”,该框返回输入值。如果用户单击“取消”,该框返回 NULL。

var person = prompt("请输入您的姓名", "比尔盖茨");
if (person != null) {
    console.log(person);
}

定时事件

  • setTimeout(function, milliseconds)

    在等待指定的毫秒数后执行函数。

  • setInterval(function, milliseconds) 单位是毫秒

    等同于 setTimeout(),但持续重复执行该函数。

  • setInterval() 方法:定时器

    window.setInterval(function, milliseconds)

Navigate对象

​ 获取UA伪装:navigator.userAgent

Location
console.log(location);          //输出location对象
console.log(location.href);     //输出当前地址的全路径地址
console.log(location.origin);   //输出当前地址的来源
console.log(location.protocol); //输出当前地址的协议
console.log(location.hostname); //输出当前地址的主机名
console.log(location.host);     //输出当前地址的主机
console.log(location.port);     //输出当前地址的端口号
console.log(location.pathname); //输出当前地址的路径部分
console.log(location.search);   //输出当前地址的?后边的参数部分

跳转:location.assign(“https://www.baidu.com”)

刷新:location.reload(true)

HIstory对象

退回到上一个页面:history.back();

跳转到下一个页面:history.forward();

异常处理:

try {
    // 可能发生异常的代码
} catch (error) {
    // 发生错误执行的代码
} finally {
    // 无论是否出错都会执行的代码
}

eval:

eval(”字符串“) eval会执行js代码

eval("alert('Hello')");

JSON:

在JSON中,每一个数据项,都是由一个键值对组成的,但是键必须是字符串,且由双引号包围,而值必须是以下数据类型之一:

  • 字符串(在 JSON 中,字符串值必须由双引号编写)
  • 数字
  • 对象(JSON 对象) { }
  • 数组 [ ]
  • 布尔
  • null
JSON.parse()

​ 当你有一个包含JSON字符串的变量时,你可以使用JSON.parse()将其转换为JavaScript对象。

var jsonString = '{"name":"John","age":30,"city":"New York"}';
var jsonObject = JSON.parse(jsonString);
console.log(jsonObject.name); // 输出:John
console.log(jsonObject.age);  // 输出:30
console.log(jsonObject.city); // 输出:New York
JSON.stringify()

jsonString将成为一个包含转换后的JSON字符串的变量:

var data = { name: "John", age: 30, city: "New York" };
var jsonString = JSON.stringify(data);
console.log(jsonString); //{"name":"John","age":30,"city":"New York"} 
console.log(data) //{ name: 'John', age: 30, city: 'New York' }

AJAX:

创建 XMLHttpRequest :

variable = new XMLHttpRequest();//所有现代浏览器

兼容所有浏览器的写法:

var xhttp;
if (window.XMLHttpRequest) {
    xhttp = new XMLHttpRequest();
} else {
    // code for IE6, IE5
    xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

在这里插入图片描述

注意 send()这个,很多XHR页面都有这个方法。

在这里插入图片描述

GET请求

users.json:

[
  {"name":"孙悟空","age":18,"gender":"男"},
  {"name":"猪八戒","age":19,"gender":"男"},
  {"name":"唐僧","age":20,"gender":"男"},
  {"name":"沙和尚","age":21,"gender":"男"}
]

index.html:

//步骤一:创建异步对象
var ajax = new XMLHttpRequest();
//步骤二:参数一是请求的类型,参数二是需要发送数据的地址
ajax.open("get", "users.json");
//步骤三:发送请求
ajax.send();
//步骤四:注册事件 onreadystatechange 状态改变就会调用
ajax.onreadystatechange = function () {
    if (ajax.readyState == 4 && ajax.status == 200) {
        //步骤五:如果能够进到这个判断,说明数据完美的回来了,并且请求的页面是存在的
        console.log(ajax.responseText);//输入响应的内容
    }
};

POST请求:

users.json:

[
  {"name":"孙悟空","age":18,"gender":"男"},
  {"name":"猪八戒","age":19,"gender":"男"},
  {"name":"唐僧","age":20,"gender":"男"},
  {"name":"沙和尚","age":21,"gender":"男"}
]

index.html:

//步骤一:创建异步对象
var ajax = new XMLHttpRequest();
//步骤二:设置请求的类型及数据所在的地址,注意:post请求一定要添加请求头才行不然会报错
ajax.open("post", "users.json");
//添加请求头
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//步骤三:发送请求
ajax.send();
//步骤四:注册事件 onreadystatechange 状态改变就会调用
ajax.onreadystatechange = function () {
    //步骤五:如果能够进到这个判断,说明数据完美的回来了,并且请求的页面是存在的
    if (ajax.readyState == 4 && ajax.status == 200) {
        console.log(ajax.responseText);//输入响应的内容
    }
};

整合get和post:

var Ajax = {
    get: function (url, fn) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304) {
                fn.call(this, xhr.responseText);
            }
        };
        xhr.send();
    },
    post: function (url, data, fn) {
        var xhr = new XMLHttpRequest();
        xhr.open("POST", url, true);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
                fn.call(this, xhr.responseText);
            }
        };
        xhr.send(data);
    }
};

// 演示GET请求
Ajax.get("users.json", function (response) {
    console.log(response);
});

// 演示POST请求
Ajax.post("users.json", "", function (response) {
    console.log(response);
});

Cookie:

​ 保存在本地的用户信息,以后发送请求会携带cookie向服务器发送请求,这样用户就不用输入相关信息了。

在这里插入图片描述

document.cookie = "username=zhangsan";//创建一个cookie
var cookies = document.cookie;
console.log(cookies);

cookie中的expires:

​ 即过期时间,过期后自动清除。

document.cookie = "username=zhangsan; expires=Thu, 18 Dec 2043 12:00:00 GMT";

cookie中的path:

​ 即可以使用 path 参数告诉浏览器 cookie 的路径,/表示当前页面

document.cookie = "username=zhangsan; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";

ES6新语法:

反引号(`):

// `` 用于多行字符串文本
let str = `<ul>
               <li>沈腾</li>
               <li>玛丽</li>
               <li>魏翔</li>
               <li>艾伦</li>
           </ul>`;
console.log(str);

字符串格式化:

//${变量}  表示占位符
let name = '小可爱';
let result = `欢迎${name}访问我的文章`;
console.log(result);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/182460.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python如何快速查找到想要的文档

字多不看版&#xff0c;直接体验 待补充 演示代码 # -*- coding:UTF-8 -*-# region 导入必要的依赖包 import os import subprocess from enum import Enum模块名 pyperclip try:import pyperclip # 需要安装 pyperclip 模块&#xff0c;以支持粘贴板操作 except ImportEr…

激光雷达与惯导标定 | Lidar_IMU_Init : 编译

激光雷达与惯导标定&#xff1a;Lidar_IMU_Init 编译 功能包安装安装ceres-solver-2.0.0 &#xff08;注意安装2.2.0不行&#xff0c;必须要安装2.0.0&#xff09; LI-Init是一种鲁棒、实时的激光雷达惯性系统初始化方法。该方法可校准激光雷达与IMU之间的时间偏移量和外部参数…

【Spring】 IoCDI

回顾 企业命名规范 大驼峰:BookDao(首字母都大写) 类名 小驼峰:bookDao(第一个字母小写) 方法名 蛇形:book_dao(小写下划线_) 数据库 串形:book-dao(小写连字符-) 项目文件夹 各种注解 学习Spring MVC, 其实就是学习各种Web开发需要⽤的到注解 a. RequestMapping: 路由…

(一)C语言之入门:使用Visual Studio Community 2022运行hello world

使用Visual Studio Community 2022运行c语言的hello world 一、下载安装Visual Studio Community 2022 与 新建项目二、编写c helloworld三、编译、链接、运行 c helloworld1. 问题记录&#xff1a;无法打开源文件"stdio.h"2. 问题记录&#xff1a;调试和执行按钮是灰…

Leetcode算法系列| 1. 两数之和(四种解法)

目录 1.题目2.题解解法一&#xff1a;暴力枚举解法二&#xff1a;哈希表解法解法三&#xff1a;双指针(有序状态)解法四&#xff1a;二分查找(有序状态) 1.题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数…

前端 vue 面试题(二)

文章目录 如何让vue页面重新渲染组件间通信vue为什么要mutation、 action操作插槽、具名插槽、作用域插槽vue编译使用的是什么库&#xff1f;vue怎么实现treeshakingwebpack实现treeshaking为什么只有es module 能支持 tree shaking mixin 的作用mixin的底层原理nexTick原理vue…

小辰的智慧树(差分+前缀和)

登录—专业IT笔试面试备考平台_牛客网 1.考虑总长度之和不能超过m&#xff0c;2考虑限制每棵树高度不能低于ci&#xff0c;如果用二分最短输能截到的高度&#xff0c;还要另外去判断&#xff0c;是否每棵树mid都能严格大于ci &#xff0c;这样容易超时&#xff0c;换个角度&…

14 redis全量复制与部分复制

1、设置主服务器的地址和端口 首先是在从服务器设置需要同步的主服务器信息&#xff0c;包括机器IP, 端口。 主从复制的开启&#xff0c;完全是在从节点发起的。不需要我们在主节点做任何事情。 从节点开启主从复制&#xff0c;有3种方式 配置文件&#xff1a;在从服务器的配…

使用【画图】软件修改图片像素、比例和大小

打开电脑画图软件&#xff0c;点击开始 windows附件 画图 在画图软件里选择需要调整的照片&#xff0c;点击文件 打开 在弹出窗口中选择照片后点击打开 照片在画图软件中打开后&#xff0c;对照片进行调整。按图中顺序进行 确定后照片会根据设定的值自动调整 保存…

P6 C++控制流语句(continue, break, return)

前言 今天我们讲的是控制流语句&#xff0c;本期内容是上期课程的延续。 控制流语句一般与循环语句一起工作&#xff0c;它们让我们可以更好的控制这些循环的实际运行。 我们有三个主要的控制流语句可以使用&#xff0c;continue 、break 和 return&#xff0c;它们有不同的…

CCFCSP试题编号:201803-2试题名称:碰撞的小球

一、题目描述 二、思路 1.首先妾身分析这个题目&#xff0c;想要解题&#xff0c;得得解决2个问题。 1&#xff09;判断小球到达端点或碰撞然后改变方向&#xff1b; 2&#xff09;每时刻都要改变位置 两个问题都比较好解决&#xff0c;1&#xff09;只要简单判断坐标&…

【Vue】核心特性(响应式)

响应式&#xff1a; 数据变化&#xff0c;视图自动更新 接下来使用一个例子来体现一下什么是响应式 案例一&#xff1a; 访问数据&#xff0c;视图自动更新 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><…

12个最佳WordPress投票插件

您是否正在为您的网站寻找WordPress投票插件&#xff1f; WordPress投票插件可让您轻松地在您的网站上进行民意调查&#xff0c;用户可以投票。这是在收集见解的同时建立用户参与度的有效策略。 在本文中&#xff0c;我们精心挑选了最好的WordPress投票插件&#xff0c;可帮助…

【C/PTA】函数专项练习(四)

本文结合PTA专项练习带领读者掌握函数&#xff0c;刷题为主注释为辅&#xff0c;在代码中理解思路&#xff0c;其它不做过多叙述。 目录 6-1 计算A[n]1/(1 A[n-1])6-2 递归实现顺序输出整数6-3 自然数的位数(递归版)6-4 分治法求解金块问题6-5 汉诺塔6-6 重复显示字符(递归版)…

代码随想录算法训练营第五十二天|300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

文档讲解&#xff1a;代码随想录 视频讲解&#xff1a;代码随想录B站账号 状态&#xff1a;看了视频题解和文章解析后做出来了 300.最长递增子序列 class Solution: # 2516 ms, faster than 64.96%def lengthOfLIS(self, nums: List[int]) -> int:n len(nums)dp [1] * n…

黑马点评-10实现用户点赞和点赞排行榜功能

用户点赞功能 如果用户只要点赞一次就对数据库中blog表中的liked字段的值加1就会导致一个用户无限点赞 PutMapping("/like/{id}") public Result likeBlog(PathVariable("id") Long id) {// 修改点赞数量,update tb_blog set liked liked 1 where id …

JavaScript编程基础 – 布尔值(Booleans)

JavaScript编程基础 – 布尔值(Booleans) Javascript Programming Essentials – Booleans 一个JavaScript布尔值包含两个值中的一个&#xff0c;即 true 或者 false。 本文简要介绍JavaScript布尔值的具体应用&#xff0c;以及可能作为对象的布尔值等。 1. 布尔值(Booleans)…

Py之PyPDF2:PyPDF2的简介、安装、使用方法之详细攻略

Py之PyPDF2&#xff1a;PyPDF2的简介、安装、使用方法之详细攻略 目录 PyPDF2的简介 PyPDF2的安装 PyPDF2的使用方法 1、基础用法 PyPDF2的简介 PyPDF2是一个免费的、开源的纯python PDF库&#xff0c;能够拆分、合并、裁剪和转换PDF文件的页面。它还可以为PDF文件添加自定…

springcloud超市管理系统源码

技术说明&#xff1a; jdk1.8&#xff0c;mysql5.7&#xff0c;idea&#xff0c;vscode springcloud springboot mybatis vue elementui mysql 功能介绍&#xff1a; 后台管理&#xff1a; 统计分析&#xff1a;查看用户&#xff0c;商品&#xff0c;销售数量&#xff1b;…

JavaWeb——感谢尚硅谷官方文档

JavaWeb——感谢尚硅谷官方文档 XML一、xml简介二、xml的语法1、文档申明2、xml注释3、xml元素4、xml属性5、xml语法规则 三、xml解析技术1、使用dom4j解析xml Tomcat一、JavaWeb的概念二、web资源的分类三、常见的web服务器四、Tomcat的使用1、安装2、Tomcat的目录介绍3 启动T…