我有一个 Java 应用程序,它将解析 html 页面并从中提取数据。目前,我有一个类作为模板或说明如何阅读特定网页。该应用程序将需要从几个不同的站点读取,这些站点的格式将不同。我不想为每种格式创建一个新的模板类,而是希望能够读取随附的 XML 文件(或其他文档),该文件将提供有关哪些数据和提取位置的说明。
我试图在互联网上搜索如何做到这一点,但我猜我没有问正确的问题或使用正确的关键字。
该解决方案不必使用 XML 作为模板,但这是我的第一个想法。
谁能指出我正确的方向?
您可以保留xpath表达式,而不是在 xml 中使用模板,这些表达式映射到您正在阅读的每个站点的所需数据。然后,随着您正在抓取的页面发生变化,您只需更新该站点的 xpath 表达式即可。
Extractor
用于ExtractionInstructions
从单一来源提取感兴趣的数据。您可以稍后从提取器中检索提取的数据。
在这个高级设计中
我建议使用JSoup作为基础库来构建这些抽象。
实际上我以前做过类似的事情,但它相当复杂。基本上我做了一个插件系统(像 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 提取器和/或 Regex Extractor... 等。您将策略按照您希望它们运行的顺序排列。
在需要启发式的数据挖掘时,我一直使用这种模式。对于提取讨厌的 HTML(在您的评论中提到的其他人),我推荐Jericho或JSoup(在这种情况下,您可以制定 Jericho 策略并添加到链中)。