可配置的HTML信息提取

时间:2019-06-23 12:09:56

标签: java web-crawler information-retrieval information-extraction

场景:

我正在使用搜寻器进行一些HTML信息提取。现在,大多数提取规则都是硬编码的(不是标签或类似的东西,而是循环,嵌套元素等)

例如,一项常见任务如下:

  1. 获取ID为X的表。如果该表不存在,则可能存在其他机制,因此请查找触发的信息
  2. 找到包含一些信息的行。通常,匹配项是针对特定列的正则表达式。
  3. 在其他列中检索数据(通常在td中标记,或先前在标头中检测到)

我目前这样做的方式是:

  1. 查询以获取ID为X的第一个表的主体(X在配置文件中)。我列表中的某些网站存在错误,并且在与表-.-
  2. 不同的元素上重复了该id
  3. 遍历有趣的单元格,对cell.text()执行regexp(regexp在配置文件中)
  4. 获取匹配单元格的父行,并从该行获取我需要的单元格(该行的标识符在配置文件中)

在大多数情况下,所有这些硬编码(列名,表ID等除外)给我带来的好处或易于实现,并且比通用解析器效率更高,但是,它的可配置性较差,并且某些更改目标网站迫使我处理代码,这使得委派任务变得更加困难。

问题

是否有任何语言(最好使用Java实现)可以一致地定义提取规则,例如?我正在使用css样式的选择器来执行某些任务,但其他任务却并非如此简单,所以我最好的猜测是,必须有某种扩展使非程序员维护者可以按需添加/修改规则。

如果有的话,我会接受基于Nutch的答案,尽管我们正在研究将爬虫迁移到坚果,但是,我更喜欢通用的Java解决方案。

我当时正在考虑编写一个解析器生成器并创建自己的规则集,以允许用户/维护者生成解析器,但这确实是无缘无故地重新发明轮子的感觉。

1 个答案:

答案 0 :(得分:0)

我正在做一些类似的事情-不完全是您要搜索的内容,但是也许您可以得到一些想法。

首先是爬行部分: 我在Python 3.7上使用Scrapy。 对于我的项目,这带来了优势,即它非常灵活且易于构建的爬网框架。请求之间的延迟,HTTP标头语言等之类的东西大多数都可以配置。

对于信息提取部分和规则: 在我的上一代搜寻器中(我正在研究第三代,第二代仍在运行,但伸缩性不高),我使用JSON文件为每个页面输入XPath / CSS规则。因此,在启动搜寻器时,我已经为当前正在爬网的一个特定页面加载了JSON文件,并且一个通用的搜寻器知道了基于加载的JSON文件提取的内容。

这种方法难以扩展,因为每个域必须创建一个配置文件。 目前,我仍在使用Scrapy,其中包含700个要爬网的域的起始列表,并且该爬网程序现在仅负责将整个网站下载为HTML文件。 这些通过外壳程序脚本存储在tar归档文件中。 然后,Python脚本将遍历shell脚本的所有成员,并分析内容以获取我要提取的信息。

在这里,正如您所说,这有点像重新发明轮子或在现有库周围编写包装纸。

在Python中,您可以使用BeautifulSoup删除脚本和样式等所有标记。 然后,您可以提取所有文本。 或者您只关注表格,将所有表格提取到字典中,然后可以使用正则表达式或类似内容进行分析。 有DragNet之类的库可用于删除样板。 在how to extract table structured information上有一些特定的方法。