最近做一些抓取工作,从一个行业的网站上抓取想要的信息。由于各个网站的页面各不一样,一般的实现是为某一类特定的页面编写一个解析器。如果抓取的网站少还好点,但是当网站数量多时,这就是最笨的方法了。
所以抽了点时间实现了一个基于XML的可配置的解析工具。功能只要有:
- 支持正则表达式抽取数据
- 支持SPEL运算,需要spring的相关包
- 支持工具类的方法调用,对抽取数据进行后续处理
- xml描述继承
- 数据校验(校验失败时抛出异常,包那个字段在那个url页面解析过程中发生了问题)
使用:只需要提交要抽取的页面的URL。返回指定对象。这样做其实开发工作并没有很大的减少,只是更便于管理和扩展。
? ? 此工具大致由以下几部分组成:
- 控制器ExtractorController,主要功能有读取配置文件和对外提供统一接口 Object extractHtml(String url)。
- 读取配置文件时初始化一个配置文件目录。按照配置文件之间的依赖关系读取配置元数据,存入Extractor对象。
- 配置文件主要分为字段定义、预定义两部分。
- 预定义主要是一些在解析页面过程中的一些临时变量(如用正则获取的一些临时字符串,或一些http请求内容,一些页面的部分数据是通过ajax加载的)。
- 字段的定义,字段名称和对象名称一致,包含一个required属性,用于校验判断抽取的正确性。
- 字段包含若干个处理器。处理器的执行按照配置文件的先后顺序依次执行,下一步执行默认以上一步的结果作为数据。
- 处理器包含默认值处理器valueProcess 、正则处理器 RegexProcess ?Spel表达式处理器SpelProcess、工具 方法处理器ToolProcess、和数据请求处理器ContentRequestProcess、字段处理器FieldProcess等。
- valueProcess?将字段设置一个指定的值,类似常量概念。
- RegexProcess 利用上下文抽取匹配的数据。上下文一般指的是上一部的操作、或者指定的变量、 如果没有上一步则为最开始获取传入url的内容。
- SpelProcess主要是针对当前上下文做一些运算,具体参考Spring的Spel文档。
- ToolProcess主要是针对当前上下文调用一些工具类的方法。工具类可以是自己的也可以是一些已有的(如apache commons 中常用得NumberUtils)
- ContentRequestProcess用于请求一些Ajax数据。(有些开源项目可以执行js如cobra,然后将修改反映到DOM树种。但个人觉得这样有点复杂化,毕竟要获取的数据源不是很多)。 ContentRequestProcess可能要依赖于其他一些处理 如预定义的处理或者一些字段的数据的获取。
- 每一个处理器的操作都会缓存到一个数据容器中DataContainer(HashMap的一个扩展)。
- FieldProcess字段处理器依次调用字段的处理器,并返回最后一个的处理器返回的值。
- Process的一个抽象方法是Object process(DataContainer dataContainer);
- 每一个Process都有对应的Setting对象。如RegexProcess对应的Setting对象是RegexSetting。Setting对应于配置文件中的相应元素,并最后装配成Extractor对象。
建议:将数据类型简化,尽量使用String类型 ,不要做过多的数据处理工作,把这部分工作留在抽取后进行。
今天就写到这里以后有时间和实际使用情况再补上!