天天看点

实现MHT文件格式的解析和内容抽取

由于我们的业务系统中有大量的MHT格式的资料,需要对其建立索引,搜索很久了一直没有找到相关解析的类库,只好自己动手丰衣足食了。已实现内容的提取以及和lucene的整合,稍后会完善编码检测及其他内容的提取,做一个完整的parser出来。  

文本内容提取:  首先提取html部分的内容,解码之后使用nekoHtml提取文本内容;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

<code>public</code> <code>class</code> <code>MhtDocHandler </code><code>extends</code> <code>HtmDocHandler {  </code>

<code>  </code> 

<code>    </code><code>private</code> <code>DOMFragmentParser parser = </code><code>new</code> <code>DOMFragmentParser();  </code>

<code>    </code><code>public</code> <code>Document getDocument(InputStream is) </code><code>throws</code> <code>DocumentHandlerException {  </code>

<code>        </code><code>DocumentFragment node = </code><code>new</code> <code>HTMLDocumentImpl().createDocumentFragment();  </code>

<code>        </code><code>try</code> <code>{  </code>

<code>            </code><code>String mhts = IOUtils.toString(is);  </code>

<code>            </code><code>int</code> <code>a1 = mhts.indexOf(</code><code>"&lt;HTML"</code><code>);  </code>

<code>            </code><code>int</code> <code>a2 = mhts.indexOf(</code><code>"&lt;/HTML&gt;"</code><code>);  </code>

<code>            </code><code>String html = mhts.substring(a1, a2 + </code><code>8</code><code>);  </code>

<code>            </code><code>//在mht中文本按照QuotedPrintable格式编码  </code>

<code>        </code><code>html = decodeQuotedPrintable(html, </code><code>"UTF-8"</code><code>);  </code>

<code>            </code><code>StringReader r = </code><code>new</code> <code>StringReader(html);  </code>

<code>            </code><code>parser.parse(</code><code>new</code> <code>InputSource(r), node);  </code>

<code>        </code><code>}  </code>

<code>        </code><code>catch</code> <code>(Exception e) {  </code>

<code>            </code><code>throw</code> <code>new</code> <code>DocumentHandlerException(</code><code>"Cannot parse MHT document: "</code><code>, e);  </code>

<code>        </code><code>Document doc = </code><code>new</code> <code>Document();  </code>

<code>        </code><code>StringBuffer sb = </code><code>new</code> <code>StringBuffer();  </code>

<code>        </code><code>getText(sb, node, </code><code>"title"</code><code>);  </code>

<code>        </code><code>String title = sb.toString().trim();  </code>

<code>        </code><code>sb.setLength(</code><code>0</code><code>);  </code>

<code>        </code><code>getText(sb, node, </code><code>"body"</code><code>);  </code>

<code>        </code><code>String text = sb.toString().trim();  </code>

<code>        </code><code>if</code> <code>(!title.equals(</code><code>""</code><code>)) {  </code>

<code>            </code><code>doc.add(</code><code>new</code> <code>Field(WikiDOC.DOC_TITLE, title,   </code>

<code>                                  </code><code>Field.Store.YES, Field.Index.TOKENIZED,   </code>

<code>                                       </code><code>Field.TermVector.WITH_POSITIONS_OFFSETS));  </code>

<code>        </code><code>if</code> <code>(!text.equals(</code><code>""</code><code>)) {  </code>

<code>            </code><code>doc.add(</code><code>new</code> <code>Field(WikiDOC.DOC_CONTENT, text,   </code>

<code>                                       </code><code>Field.Store.COMPRESS, Field.Index.TOKENIZED,   </code>

<code>                                           </code><code>Field.TermVector.WITH_POSITIONS_OFFSETS));  </code>

<code>        </code><code>return</code> <code>doc;  </code>

<code>    </code><code>}  </code>

<code>    </code><code>public</code> <code>static</code> <code>String decodeQuotedPrintable(String str, String encoding) {  </code>

<code>        </code><code>if</code> <code>(str == </code><code>null</code><code>) {  </code>

<code>            </code><code>return</code> <code>null</code><code>;  </code>

<code>            </code><code>//str = str.replaceAll("=\n", "");//??  </code>

<code>            </code><code>byte</code><code>[] bytes = str.getBytes(</code><code>"US-ASCII"</code><code>);  </code>

<code>            </code><code>ByteArrayOutputStream buffer = </code><code>new</code> <code>ByteArrayOutputStream();  </code>

<code>            </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i &lt; bytes.length; i++) {  </code>

<code>                </code><code>int</code> <code>b = bytes[i];  </code>

<code>                </code><code>if</code> <code>(b == </code><code>'='</code><code>) {  </code>

<code>                    </code><code>int</code> <code>u = Character.digit((</code><code>char</code><code>) bytes[++i], </code><code>16</code><code>);  </code>

<code>                    </code><code>int</code> <code>l = Character.digit((</code><code>char</code><code>) bytes[++i], </code><code>16</code><code>);  </code>

<code>                    </code><code>if</code> <code>(u == -</code><code>1</code> <code>|| l == -</code><code>1</code><code>) {</code><code>//??  </code>

<code>                        </code><code>continue</code><code>;  </code>

<code>                    </code><code>}  </code>

<code>                    </code><code>buffer.write((</code><code>char</code><code>) ((u &lt;&lt; </code><code>4</code><code>) + l));  </code>

<code>                </code><code>} </code><code>else</code> <code>{  </code>

<code>                    </code><code>buffer.write(b);  </code>

<code>                </code><code>}  </code>

<code>            </code><code>}  </code>

<code>            </code><code>return</code> <code>buffer.toString(encoding);  </code>

<code>            </code><code>e.printStackTrace();  </code>

<code>            </code><code>return</code> <code>str;  </code>

<code>}</code>

 本文转自 独孤环宇 51CTO博客,原文链接:http://blog.51cto.com/snowtiger/1963087

继续阅读