对HTML文档进行标记

时间:2017-11-29 09:58:17

标签: python html nlp spacy

我有一个HTML文档,我想使用spaCy对其进行标记,同时将HTML标记保留为单个标记。 这是我的代码:

import spacy
from spacy.symbols import ORTH
nlp = spacy.load('en', vectors=False, parser=False, entity=False)

nlp.tokenizer.add_special_case(u'<i>', [{ORTH: u'<i>'}])
nlp.tokenizer.add_special_case(u'</i>', [{ORTH: u'</i>'}])

doc = nlp('Hello, <i>world</i> !')

print([e.text for e in doc])

输出结果为:

['Hello', ',', '<', 'i', '>', 'world</i', '>', '!']

如果我在标签周围放置空格,如下所示:

doc = nlp('Hello, <i> world </i> !')

输出是我想要的:

['Hello', ',', '<i>', 'world', '</i>', '!']

但我想避免对HTML进行复杂的预处理。

我知道如何处理这个问题?

2 个答案:

答案 0 :(得分:2)

您需要创建自定义标记器。

您的自定义令牌生成器将与spaCy的令牌生成器完全相同,但是将从前缀和后缀中删除“ <”和“>”符号,并且还会添加一个新的前缀和一个新的后缀规则。

代码:

import spacy
from spacy.tokens import Token
Token.set_extension('tag', default=False)

def create_custom_tokenizer(nlp):
    from spacy import util
    from spacy.tokenizer import Tokenizer
    from spacy.lang.tokenizer_exceptions import TOKEN_MATCH
    prefixes =  nlp.Defaults.prefixes + ('^<i>',)
    suffixes =  nlp.Defaults.suffixes + ('</i>$',)
    # remove the tag symbols from prefixes and suffixes
    prefixes = list(prefixes)
    prefixes.remove('<')
    prefixes = tuple(prefixes)
    suffixes = list(suffixes)
    suffixes.remove('>')
    suffixes = tuple(suffixes)
    infixes = nlp.Defaults.infixes
    rules = nlp.Defaults.tokenizer_exceptions
    token_match = TOKEN_MATCH
    prefix_search = (util.compile_prefix_regex(prefixes).search)
    suffix_search = (util.compile_suffix_regex(suffixes).search)
    infix_finditer = (util.compile_infix_regex(infixes).finditer)
    return Tokenizer(nlp.vocab, rules=rules,
                     prefix_search=prefix_search,
                     suffix_search=suffix_search,
                     infix_finditer=infix_finditer,
                     token_match=token_match)



nlp = spacy.load('en_core_web_sm')
tokenizer = create_custom_tokenizer(nlp)
nlp.tokenizer = tokenizer
doc = nlp('Hello, <i>world</i> !')
print([e.text for e in doc])

答案 1 :(得分:0)

为了记录,这可能变得更容易了:使用当前版本的 Spacy,您不再需要创建自定义标记器。只需 1. 扩展中缀(以确保标签与单词分开),以及 2. 作为特殊情况添加标签:

import spacy
from spacy.symbols import ORTH

nlp = spacy.load("en_core_web_trf")

text = """Hello, <i>world</i> !"""
infixes = nlp.Defaults.infixes + [r'(<)']
nlp.tokenizer.infix_finditer = spacy.util.compile_infix_regex(infixes).finditer
nlp.tokenizer.add_special_case(f"<i>", [{ORTH: f"<i>"}])    
nlp.tokenizer.add_special_case(f"</i>", [{ORTH: f"</i>"}])    

doc = nlp(text)
print([e.text for e in doc])

打印:

['Hello', ',', '<i>', 'world', '</i>', '!']

(这或多或少是 https://stackoverflow.com/a/66268015/1016514 的精简版)