【问题标题】:How to use XML as template for Java to read HTML?如何使用 XML 作为 Java 的模板来读取 HTML?
【发布时间】:2012-11-08 23:18:02
【问题描述】:

我有一个 Java 应用程序,它将解析 html 页面并从中提取数据。目前,我有一个类作为模板或说明如何阅读特定网页。该应用程序将需要从几个不同的站点读取,这些站点的格式将不同。我希望能够读取随附的 XML 文件(或其他文档),而不是为每种格式创建一个新的模板类,该文件将提供有关哪些数据和提取位置的说明。

我试图在互联网上搜索如何做到这一点,但我猜我没有问正确的问题或使用正确的关键字。

解决方案不一定要用 XML 作为模板,但这是我的第一个想法。

谁能指出我正确的方向?

【问题讨论】:

    标签: java html xml templates


    【解决方案1】:

    Extractor 使用 ExtractionInstructions 从单一来源提取感兴趣的数据。您可以稍后从提取器中检索提取的数据。

    在这个高级设计中

    • 来源:您要从中提取相同数据的每个页面
    • 提取器:每次提取在单个源上运行 1 个实例
    • ExtractionInstructions:一组指令明确描述从单一来源提取数据的方法。
      • 您可以通过以下方式明确指定指令
        • 标签 ID 和/或
        • 使用 CSS 3 选择器和/或
        • xpath 等
      • 您可以使用以上所有方法的组合,将它们链接在一起(责任链模式)以获得更多的成功率。想法是,如果使用 1 种提取类型找不到数据,那么您可以尝试使用其他选项,直到找到数据或用完说明为止)。

    我建议使用JSoup 作为基础库来构建这些抽象。

    【讨论】:

    • 我明白你的意思了,谢谢。这是我认为我正在寻找的方向。你的高级设计给了我一些关于如何设计和实现这样的东西的想法。我已经在使用 Jsoup 来解析 html,所以连接一个提取器应该不会造成太大的问题。
    【解决方案2】:

    您可以保留xpath 表达式,而不是使用 xml 中的模板,这些表达式映射到您正在阅读的每个站点的所需数据。然后,随着您要抓取的页面发生变化,您只需更新该站点的 xpath 表达式即可。

    【讨论】:

    • 这听起来像我要找的。谢谢,我从来没有用过xpath,但我会看看。
    • 唯一的问题是当你的 HTML 不是格式良好的 XML 时,在你不能使用 XPath 的情况下
    • @AmirPashazadeh 有一点,你必须确保在使用 xpath 之前 html 已经整理好并且格式正确。
    • @AmirPashazadeh - 是的,你可以。使用像 the Validator.nu HTML parser 这样好的 HTML 解析器,无论标记的格式如何,它都会构建一个可以与任何标准 XML 工具链(包括 XPath)一起使用的 DOM。
    【解决方案3】:

    实际上我以前做过类似的事情,但它相当复杂。基本上我做了一个插件系统(像 Maven 一样恶心),你可以参数化提取插件。

    您可以使用 Spring Bean XML 作为您的 DSL 来做到这一点。

    <bean id="strategy1"  class="absolute.class.name">
    </bean>
    
    <bean id="extractorExecutor" class="class.to.extractorExecutor">
       <property name="strategies">
        <list>
            <item ref="strategy1" />
            <item ref="strategy2" />
         </list>
        </property> 
    </bean>
    

    您的提取器基本上循环通过一堆实现如下接口的 bean:

    public interface ExtractStrategy {
        /**
         * null means skip this extractor and go to the next one.
         */
        public Extracted extract(String data);
    }
    

    在你的提取器中你这样做:

    for (ExtractorStrategy e : strategies) {
        Extracted ex = e.extract(data);
        if (ex != null) break;
    }
    

    Spring 称之为解析器链模式,也有人称之为策略模式。

    然后你可以像@digitaljoel所说的那样制作一个XPath提取器和/或一个正则表达式提取器......等等。 您可以按照您希望它们运行的​​顺序排列策略。

    当您需要启发式 时,我一直使用这种模式。对于提取讨厌的 HTML(在您的 cmets 中提到的其他人),我推荐 JerichoJSoup(在这种情况下,您制定 Jericho 策略并添加到链中)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-05
      • 2011-07-25
      • 1970-01-01
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      相关资源
      最近更新 更多