基于 Java 模板提取网页信息

现在我使用Jsoup从一些第三方网页中提取某些信息(不是所有文本),我定期这样做。这工作正常,直到某些网页的HTML更改,这种更改会导致现有Java代码的更改,这是一项繁琐的任务,因为这些网页更改非常频繁。此外,它还需要程序员来修复Java代码。以下是我感兴趣的网页上的HTML代码示例:

<div>
<p><strong>Score:</strong>2.5/5</p>
<p><strong>Director:</strong> Bryan Singer</p>
</div>
<div>some other info which I dont need</div>

现在这是我想做的,我想在本地保存这个网页(一个HTML文件)并从中创建一个模板,比如:

<div>
<p><strong>Score:</strong>{MOVIE_RATING}</p>
<p><strong>Director:</strong>{MOVIE_DIRECTOR}</p>
</div>
<div>some other info which I dont need</div>

与网页的实际URL一起,这些HTML模板将成为Java程序的输入,该程序将找出这些预定义关键字的位置(例如{MOVIE_RATING}{MOVIE_DIRECTOR}),并从实际网页中提取值。

这样,我就不必在每次网页更改时都修改Java程序,我只需保存网页的HTML并用这些关键字替换数据,其余的将由程序处理。例如,将来实际的HTML代码可能如下所示:

<div>
<div><b>Rating:</b>**1/2</div>
<div><i>Director:</i>Singer, Bryan</div>
</div>

和相应的模板将如下所示:

<div>
<div><b>Rating:</b>{MOVIE_RATING}</div>
<div><i>Director:</i>{MOVIE_DIRECTOR}</div>
</div>

此外,创建这些类型的模板也可以由非程序员完成,任何人都可以编辑文件。

现在的问题是,我如何在Java中实现这一点,是否有任何现有的更好的方法来解决这个问题?

注意:在谷歌搜索时,我发现了一些研究论文,但大多数都需要一些事先学习的数据,准确性也是一个值得关注的问题。


答案 1

您给出的方法与吉尔伯特的方法非常相似,除了正则表达式部分。我不想进入丑陋的正则表达式世界,我计划将模板方法用于除电影信息(例如价格,产品规格提取等)以外的许多其他领域。

  1. 您描述的模板实际上并不是该词正常意义上的“模板”:一组静态内容,通过其中插入一堆动态内容转储到输出中。相反,它是模板的“反向” - 它是一种解析模式,被诽谤和丢弃,留下所需的参数。

  2. 由于您的网页会定期更改,因此您不希望对要解析的内容进行过于精确的硬编码,而是希望“放大”其基本功能,从而做出最少的假设。即,您希望承诺从字面上匹配关键文本(例如“Rating:”),并以更灵活的方式处理交错标记 - 忽略它并允许它更改而不会中断。"<b/>"

  3. 当您组合(1)和(2)时,您可以为结果提供您喜欢的任何名称,但IT使用正则表达式进行解析。即模板方法是使用正则表达式的解析方法 - 它们是相同的。问题是:正则表达式应该采取什么形式?

    1醛如果你使用java手工编码来进行解析,那么显而易见的答案是正则表达式格式应该只是格式。其他任何东西都是开发负担,是“非标准”的,很难维护。java.util.regex

    3B.如果你使用想要使用html感知解析器,那么jsoup是一个很好的解决方案。问题是您需要比jsoup似乎提供的更多的文本/正则表达式处理和灵活性。它似乎太局限于特定的html标签和结构,因此当页面更改时会中断。

    3C.您可以使用更强大的语法控制的通用文本解析器,例如ANTLR - 一种受backus-naur启发的语法形式用于控制解析,并插入生成器代码来处理解析的数据。在这里,解析语法表达式确实非常强大,具有复杂的规则,用于定义文本在页面上的排序方式以及文本字段和值如何相互关联。功能超出了您的要求,因为您没有处理一种语言。而且,您仍然需要描述要跳过的丑陋位 - 例如标记标记等,这是不可避免的事实。与ANTLR摔跤的第一次涉及教育投资,然后再获得生产力回报。

    三维。有没有一个Java工具只使用简单的模板类型方法来给出一个简单的答案?好吧,谷歌搜索不会给 https://www.google.com/search?q=java+template+based+parser&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-GB:official&client=firefox-a 太多的希望。我相信,任何创建这种野兽的尝试都会退化为基本的正则表达式解析或更高级的语法控制解析,因为匹配/忽略/替换文本的基本要求会推动这些方向的解决方案。其他任何东西都太简单了,无法实际工作。抱歉负面观点 - 它只是反映了问题空间。

我的投票是(3A)作为满足您需求的最简单,最强大和最灵活的解决方案。


答案 2

这里并不是一个真正基于模板的方法,但是如果您只是将选择器查询外部化到配置文件中,jsoup仍然是一个可行的解决方案。

您的非程序员甚至不必查看HTML,只需更新配置文件中的选择器即可。像SelectorGadget这样的东西将更容易地挑选出实际使用的选择器。


推荐