我平时的工作中,偶尔会用 Java 做一些解析HTML的工作。有的时候我需要删除所有的HTML标签,只保留纯文字内容。这个问题在做过一些爬虫工作的朋友来说很简单。下面来说说,我们平时使用到的集中解析的方法。
通过爬虫爬到的HTML内容,从程序角度来讲,就是一个字符串。我们可以对其按照纯文本处理的方式来处理。
我们在做文本处理的时候,第一个想到的就是正则表达式。从一个字符串中删除HTML,对于正则来说,还是比较简单的。毕竟还是有固定的格式,比如“<...>”。
我们常用的的正则就是 <[^>]> 或者 <.*?> 。
我们在使用正则的时候,需要注意的是正则默认是贪婪匹配。也就是说,正则表达式<.*> 能够匹配到更多的HTML内容,而不是单个标签。
现在,让我们测试一下它是否能从HTML源中删除标签。
在我们测试删除HTML标签之前,首先让我们创建一个HTML例子,例如example1.html。
<!DOCTYPE html>
<html>
<head>
<title>这是标题</title>
</head>
<body>
<p>
如果应用程序X没有启动,可能的原因是<br/>
1. <a href="https://maven.apache.org">Maven</a>没有安装<br/>
2. 磁盘空间不足<br/>
3. 内存不足
</p>
</body>
</html>
现在,让我们写一个测试,用String.replaceAll()来删除HTML标签。
String html = ... // load example1.html
String result = html.replaceAll("<[^>]`>", "");
System.out.println(result);
如果我们运行这个测试方法,我们会看到结果。
这是标题
如果应用程序X没有启动,可能的原因是
1.Maven没有安装
2.磁盘空间不足
3.没有足够的内存
输出结果保留了剥离后的HTML的空白处。我们在处理提取的文本时,可以很容易地删除或跳过这些空行或空白处。
我们刚才已经看到了,通过使用Regex来删除HTML标签是非常简单。但是粗暴的使用这种方法会有很多问题,我们不能预测最终的结果会是怎么样的。
例如,一个HTML文档可能有<script>或<style>标签,而我们可能不希望在结果中出现它们的内容。
此外,<script>、<style>、甚至是<body>标签中的文本可能包含 <或 >字符。如果是这种情况,我们的正则方法可能会出错。
现在,让我们看看另一个例子,比如example2.html。
<!DOCTYPE HTML>
<html>
<head>
<title>这是标题</title>
</head>
<script>
// some js function
</script>
<body>
<p>
如果应用程序X没有启动,可能的原因是<br/>
1. <a
id="link"
href="http://maven.apache.org/">
Maven
</a> 没有安装<br/>
2. 磁盘空间不足 (<1G) <br/>
3. 内存不足(<64MB)<br/>
</p>
</body>
</html>
现在我们有一个<script>标签和 <字符在<body>标签内。
如果我们对example2.html使用同样的方法,我们会得到如下内容。
这是标题
// some js function
如果应用程序X没有启动,可能的原因是
1.
Maven
没有安装
2. 磁盘空间不足 (
3. 内存不足(
显然,由于"<"字符的存在,我们丢失了一些文本。所以正则在处理文本的时候并不是万能的。我们可以使用一些 HTML 解析器来做这些比较复杂的场景。
Jsoup 是一个流行的HTML解析库,如果想要从一个HTML文档中提取文本,我们可以简单地调用Jsoup.parse(htmlString).text()。
在项目中使用的时候,我们首先需要添加 jsoup 的依赖库,我们这里就通过maven的方式引入。
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.14.3</version>
</dependency>
我们用 example2.html来测试一下。
String html = ... // load example2.html
System.out.println(Jsoup.parse(html).text());
如果我们让这个方法运行,它就会打印出来。
这是标题 如果应用程序X没有启动,可能的原因是 1.Maven没有安装 2.没有足够的(<1G)磁盘空间 3.没有足够的(<64MB)内存
从输出结果可知,Jsoup已经成功地从HTML文档中提取了文本。另外,<script>元素中的文本已经被忽略了。
此外,默认情况下,Jsoup会删除所有的文本格式和空白处,比如换行符。
HTMLCleaner 也是一个HTML解析库。
首先,我们需要在pom.xml中添加HTMLCleaner 依赖。
<dependency>
<groupId>net.sourceforge.htmlcleaner</groupId>
<artifactId>htmlcleaner</artifactId>
<version>2.25</version>
</dependency>
我们可以设置[各种参数](http://htmlcleaner.sourceforge.net/parameters.php)来控制HTMLCleaner的解析行为。我们在这里使用HTMLCleaner在解析example2.html时跳过<script>元素。
String html = ... // load example2.html
CleanerProperties props = new CleanerProperties();
props.setPruneTags("script");
String result = new HtmlCleaner(props).clean(html).getText().toString();
System.out.println(result);
运行一下,HTMLCleaner将产生这样的输出。
这是标题
如果应用程序X没有启动,可能的原因是:
1.Maven没有安装
2.没有足够的(<1G)磁盘空间
3.内存不足(<64MB)
我们可以看到,<script>元素中的内容被忽略了, <br/>标签转换为提取的文本中的换行符。另外, HTMLCleaner 保留了HTML的空白内容。
在这篇文章中,我们学习了几种去除HTML的方法,我们需要注意的是,正则在文本处理的过程中并不是万能的。
判断语句:
if 语句的语法:if (condition) statement1 else statement2
如果条件计算结果为 true,则执行 statement1;如果条件计算结果为 false,则执行 statement2。
注意事项
switch 语句的语法:
语法格式
每个情况(case)都是表示“如果 expression 等于 value,就执行 statement”。
关键字 break 会使代码跳出 switch 语句。如果没有关键字 break,代码执行就会继续进入下一个 case。
关键字 default 说明了表达式的结果不等于任何一种情况时的操作(事实上,它相对于 else 从句)。
ECMAScript 和 Java 中的 switch 语句
ECMAScript 和 Java 中的 switch 语句有两点不同。在 ECMAScript 中,switch 语句可以用于字符串,而且能用不是常量的值说明情况:
1、基本数据类型都可以传递给switch case语句。
2、case语句可以是表达式
while 语句
while 语句是先测试循环。这意味着退出条件是在执行循环内部的代码之前计算的。因此,循环主体可能根本不被执行。
它的语法如下:
while
do-while 语句
do-while 语句是后测试循环,即退出条件在执行循环内部的代码之后计算。这意味着在计算表达式之前,至少会执行循环主体一次。
它的语法如下:
dowhile
for 语句
for 语句是前测试循环,而且在进入循环之前,能够初始化变量,并定义循环后要执行的代码。
它的语法如下:
for
这段代码定义了初始值为 0 的变量 i。只有当条件表达式(i < iCount)的值为 true 时,才进入 for 循环,这样循环主体可能不被执行。如果执行了循环主体,那么将执行循环后表达式,并迭代变量 i。
for循环中不会有局部变量,都是全局的变量。
for 语句是严格的迭代语句,用于枚举对象的属性或者遍历一个数组的元素。
它的语法如下:
for in
for-in语句的作用:
1. 可以用于遍历数组的元素。 注意: 使用for-in语句遍历数组元素的时候遍历出来是数组的下标。
2. 可以用于遍历对象的所有属性数据。 注意: 使用for-in语句遍历对象的属性的时候,遍历出来的是对象的属性名。
wth语句的作用: 有了 With 语句,在存取对象属性和方法时就不用重复指定参考对象。
格式:
with(obj){
操作obj的属性语句;
}
需求1:显示"*"为正方形,5行5列。
for(var i = 0 ; i<5; i++){ // 控制行数
for(var j = 0 ; j<5 ; j++){ //控制列数
document.write("* ");
}
//换行
document.write("<br/>")
}
document.write("<hr/>")
/*
需求2:输出一个直角三角形:
for(var i = 0 ; i<5; i++){
for(var j =0 ; j<=i ; j++){
document.write("* ");
}
document.write("<br/>");
}
document.write("<hr/>")
需求3:打印九九乘法表
for(var i = 1 ; i<= 9 ; i++){
for(var j = 1 ; j<=i ; j++){
document.write(i+"*"+j+"="+(i*j)+" ");
}
document.write("<br/>");
}
PS:java与javascript中有许多类似的地方,就当加固复习,具体的区别将会在后面统一整理
初学css的新手朋友经常会遇到一个问题,当文字和图片出现在同一行或者同一个div里面的时候,在浏览器中运行出来的显示效果往往是在不同的行,那么我们怎么才能在css中控制他们在同一行显示呢,其实方法有3种:1、通过添加css的“vertical-align:middle;”;2、如果图片是背景图片,可以在css中设置背景图片,然后设置文字的padding属性;3、把文字和图片分别放入不同的div中。上面三种方法都可以让图片和文字在同一行显示,下面我们用实例来应用一下。
1、在css中给div添加上“vertical-align:middle”属性
我们用“注册、登陆、找回密码”这个在实际运用中经常遇到的情况还做实例,把“注册”和“登陆”做成图片,“找回密码”设置成文字其html代码如下:
使用css的“vertical-align:middle”属性让图片和文字在同一行对齐是一种非常常用的方法,希望大家可以掌握。
2、把图片设置为背景图片
如果我们的图片本身是一个背景图片的话,可以在css中使用“background”来设置该图片,然后设置文字的padding属性就可以使他们在同一行显示了,html代码如下:
我们在css中设置了背景图片,然后又设置了文字的padding-left属性,这样,图片和文字就在同一行显示了,运行结果就不切图了,你可以自己试一下。
3、下面说下最后一种方法,分别把图片和文字放入不同的div中,然后用“margin”属性进行定位,就可以使他们显示在同一行了,html代码如下:
代码如下:
css代码如下:
代码如下:
在浏览器中运行以后,你会发现,这个方法也可以让图片和文字在同一行显示,但是看起来好像麻烦了一点,所以个人还是比较推荐第一种方法的。
学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流,裙号码:253772578【长按复制】 我们一起学Java!
*请认真填写需求信息,我们会在24小时内与您取得联系。