基于Java模板的网页信息抽取

基于Java模板的网页信息抽取,java,text-extraction,named-entity-extraction,Java,Text Extraction,Named Entity Extraction,现在我经常从一些第三方网页中提取某些信息(不是全部文本),我会定期这样做。在某些网页的HTML发生变化之前,这一切都很正常,这种变化导致现有Java代码发生变化,这是一项乏味的任务,因为这些网页变化非常频繁。它还需要程序员来修复Java代码。以下是我感兴趣的网页HTML代码示例: <div> <p><strong>Score:</strong>2.5/5</p> <p><strong>Director:</

现在我经常从一些第三方网页中提取某些信息(不是全部文本),我会定期这样做。在某些网页的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>

得分:2.5/5

导演:布莱恩·辛格

其他一些我不需要的信息
现在我想做的是,我想在本地保存这个网页(一个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>

评分:{MOVIE_RATING}

导演:{电影导演}

其他一些我不需要的信息
与网页的实际URL一起,这些HTML模板将作为Java程序的输入,Java程序将查找这些预定义关键字的位置(例如,{MOVIE\u RATING}{MOVIE\u 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>
"Score:"(.)*[0-9]\.[0-9]\/[0-9]

评级:**1/2
导演:歌手布莱恩
相应的模板如下所示:

<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>
"Score:"(.)*[0-9]\.[0-9]\/[0-9]

分级:{电影分级}
导演:{电影导演}
创建此类模板也可以由非程序员完成,任何人都可以编辑文件

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

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

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

模板方法是一种很好的方法。你在问题中给出了所有的理由

您的模板将只包含您想要处理的HTML,而不包含其他内容。这是基于你的例子的我的例子

<div>
<p><strong>Score:</strong>{MOVIE_RATING}</p>
<p><strong>Director:</strong>{MOVIE_DIRECTOR}</p>
</div>

评分:{MOVIE_RATING}

导演:{电影导演}

基本上,您可以使用Jsoup来处理模板。然后,在使用Jsoup处理web页面时,检查所有已处理的模板是否匹配

在模板匹配中,您可以在处理过的模板中找到关键字,然后在处理过的网页中找到相应的值


是的,这将需要大量的编码,并且比我描述的要困难。您的Java程序员必须将此描述分解为越来越简单的任务,直到她或他能够编写任务为止。

如果网页经常更改,那么您可能希望将对电影评级等字段的搜索限制在页面的最小部分,而忽略其他所有内容。有两种可能性:可以为每个字段使用正则表达式,也可以使用某种CSS选择器。我认为这两种方法都可以,而且“模板”都可以包含一个简单的搜索表达式列表,regex或css,您可以应用它们。只需滚动列表并提取您可以提取的内容,如果由于页面更改而找不到某个特定字段,则会失败

例如,正则表达式可以如下所示:

<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>
"Score:"(.)*[0-9]\.[0-9]\/[0-9]

(我还没有对此进行测试。)

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


您的非程序员甚至不必查看HTML,只需更新配置文件中的选择器即可。类似的内容将使您更容易选择实际使用的选择器。

或者您可以尝试不同的方法,使用我称之为“规则”而不是模板:对于页面中需要的每一条信息,您可以定义提取文本的jQuery表达式。通常,当页面变化很小时,同样编写良好的jQuery表达式仍然会给出相同的结果

然后您可以使用(Java中的jQuery)和几乎相同的表达式来获取您要查找的文本。因此,不仅仅是关于选择器,还有其他jQuery方法用于遍历/过滤DOM树

例如,某些控制器文本的规则是(类似于sudojavajerry代码):

规则中可能有更多(和更复杂)的表达式,分布在几行中,例如迭代一些节点等

如果您是OO人员,则每个规则都可以在其自己的实现中定义。如果您是groovy person,您甚至可以在需要时重写规则,而无需重新编译项目,并且仍然使用java。等等

如您所见,这里的核心思想是定义规则如何查找文本;并且不要与模式匹配,因为这可能对微小的更改很脆弱——想象一下,如果在两个div之间只添加了一个空格:)。在我的这个例子中,我使用了类似jQuery的语法(实际上,这是类似Jerry的语法,因为我们使用Java)来定义规则。这仅仅是因为jQuery流行且简单,而且您的web开发人员也知道它;最后,您可以定义自己的语法(取决于您正在使用的解析工具):例如,您可以将HTML解析为DOM树,然后使用帮助器方法编写规则,如何将其遍历到感兴趣的位置。Jerry还提供了对底层DOM树的访问

希望这有帮助


你给出的方法与吉尔伯特的方法非常相似,除了 正则表达式部分。我不想踏入丑陋的regex世界,我是 计划将模板方法用于除 瞬间