使用 Java 解析 HTML 标签

Posted

技术标签:

【中文标题】使用 Java 解析 HTML 标签【英文标题】:Parsing HTML tags using Java 【发布时间】:2014-06-06 02:50:05 【问题描述】:

我正在尝试创建一个 html 解析器来检查 HTML 标记并验证是否存在与每个打开标记相对应的结束标记。

我现在部分工作,我相信逻辑是正确的,但我在正确获取令牌时遇到问题。当我运行我拥有的代码时,它需要很多空标记,与其他非空标记相比,显然会产生错误。

我想知道如何让它从我的 HTML 文件中读取,但只将内容放入 之间的标记中。我也不希望将任何额外数据(例如 h1 标签之间的文本)考虑在内。

这是一个学校作业,我相信教授希望我们在不使用第三方程序(如 JTidy)的情况下这样做。

非常感谢任何帮助。

import java.util.Scanner;
import java.util.StringTokenizer;
import java.io.*;


public class HTMLDriver

   public static void main(String [] args) throws IOException
   
     // declare variables
     QueueReferenceBased queue = new QueueReferenceBased();

     // Create a scanner object 

     Scanner in = new Scanner(System.in);
     System.out.println("What is your html file name?");
     String fileName = in.next();

     File userFile = new File(fileName);

     if (!userFile.exists())
     
        System.out.println("File does not exist. This program will now exit.");
        System.exit(0);
     

    Scanner inputFile = new Scanner(userFile); 
    while (inputFile.hasNext())
    

        String str = inputFile.nextLine();
        StringTokenizer st = new StringTokenizer(str,"<>");

       //Adds tokens to queue
       while(st.hasMoreTokens())
       
       String token = st.nextToken();
       Tag t = new Tag(token);
       queue.enqueue(t);
      
       
    //Creates Stack
    StackReferenceBased stack = new StackReferenceBased();

    //Loops through queue if not empty
    while(!queue.isEmpty())
    
      Object obj = queue.dequeue();
      Tag t2 = (Tag)obj;

        if(t2.getOpen() == true)
        
           stack.push(t2);
        

        if(t2.getOpen() == false)
        
           if(stack.isEmpty())
           
              System.out.println("There is no match for the " + t2 + " tag");
           else
           
              Object obj2 = stack.pop();
              Tag t3 = (Tag)obj2;

              //Make tag class and check equality

              if(t2.getTag().equals(t3.getTag()))
              
                 System.out.println(t2 + " matches " + t3);
              else
              
                 System.out.println("Found " + t2 + " to match " + t3 + " terminating program");
                 System.exit(0);
              

           
        
        
     

【问题讨论】:

【参考方案1】:

不要这样做。 Html 在这方面是臭名昭著的。一些标签没有打开/关闭 -- 然后就是所有格式错误的 HTML 和浏览器的怪癖。

除非您的教授明确禁止您使用 3rd 方库,否则尝试在强大的规模上是疯狂的。在 XML 上,这是可以管理的。

如果你真的,真的必须自己做,使用正则表达式可以获得不错的结果

Pattern p = Pattern.compile("<(.*)>") // will get your started. you can then do:

Matcher m = p.matcher();
m.group( ... ) // this will get you everything between parentheses in the regex 

【讨论】:

我不能再反对了。浏览器使用相同方式的更复杂的过程来解析 HTML,按顺序标记输入流并构建标签标记堆栈。 OP 正在学习这方面的基础知识。在解析 HTML 时,正则表达式是一条死胡同。 我以前从未使用过正则表达式,所以我对如何正确使用有点困惑。我尝试搜索一下教程,但我仍然感到困惑。当我使用您发布的代码时,它给了我一个错误,指出 Matcher m = p.matcher(); 存在错误并且它不能应用于给定的类型。我应该把我的字符串作为参数放在那里吗?我也对 m.group 的工作方式感到困惑。那是我把绳子放进去的地方吗?对不起,如果我看起来很无能,这是我第一次使用正则表达式,它们对我来说有点难。 自己做这件事是死路一条。我说清楚了。如前所述,您可以使用正则表达式获得“可管理”的结果。至于浏览器,任何 Web 开发人员都可以告诉您,每个浏览器都充满了怪癖和错误。它们既可以是复杂的,也可以是错误的。 Litheon,我很高兴提供一些正则表达式指针——给我发消息。我对你最强烈的建议是验证这是你的导师想要的

以上是关于使用 Java 解析 HTML 标签的主要内容,如果未能解决你的问题,请参考以下文章

终于搞懂如何用Java去除HTML标签了

使用php simple html dom parser解析html标签

在vue中后台返回的文本包含标签如何解析为html

如何使用 BeautifulSoup 解析特定的 HTML 标签?

java 移除html标签的属性

从 XML 文件 (Java) 中的特定标签解析内容