为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Python 标记和标记 HTML 源代码

使用 Python 标记和标记 HTML 源代码

慕妹3146593 2022-01-18 17:09:48
我有一些带注释的 HTML 源代码,其中代码类似于您将使用的代码,requests并且注释是带有标记项目开始的字符索引的标签,并且例如,源代码可以是:<body><text>Hello world!</text><text>This is my code. And this is a number 42</text></body>标签可以是例如:[{'label':'salutation', 'start':12, 'end':25}, {'label':'verb', 'start':42, 'end':45}, {'label':'size', 'start':75, 'end':78}]分别指“Hello world”、“is”和“42”这三个词。我们事先知道标签没有重叠。我想处理源代码和注释以生成适合 HTML 格式的标记列表。例如,它可以在这里产生如下内容:['<body>', '<text>', 'hello', 'world', '</text>', '<text>', 'this', 'is', 'my', 'code', 'and', 'this', 'is', 'a', 'number', '[NUMBER]', '</text>', '</body>']此外,它必须将注释映射到标记化,生成与标记化长度相同的标签序列,例如:['NONE', 'NONE', 'salutation', 'salutation', 'NONE', 'NONE', 'NONE', 'verb', 'NONE', 'NONE', 'NONE', 'NONE', 'NONE', 'NONE', 'NONE', 'size', 'NONE', 'NONE']在 Python 中完成此任务的最简单方法是什么?
查看完整描述

2 回答

?
UYOU

TA贡献1878条经验 获得超4个赞

您可以使用递归BeautifulSoup来生成所有标签和内容的列表,然后可以使用它来匹配标签:


from bs4 import BeautifulSoup as soup

import re

content = '<body><text>Hello world!</text><text>This is my code. And this is a number 42</text></body>'

def tokenize(d):

  yield f'<{d.name}>'

  for i in d.contents:

     if not isinstance(i, str):

       yield from tokenize(i)

     else:

       yield from i.split()

  yield f'</{d.name}>'


data = list(tokenize(soup(content, 'html.parser').body))

输出:


['<body>', '<text>', 'Hello', 'world!', '</text>', '<text>', 'This', 'is', 'my', 'code.', 'And', 'this', 'is', 'a', 'number', '42', '</text>', '</body>']

然后,匹配标签:


labels = [{'label':'salutation', 'start':12, 'end':25}, {'label':'verb', 'start':42, 'end':45}, {'label':'size', 'start':75, 'end':78}] 

tokens = [{**i, 'word':content[i['start']:i['end']-1].split()} for i in labels]

indices = {i:iter([[c, c+len(i)+1] for c in range(len(content)) if re.findall('^\W'+i, content[c-1:])]) for i in data}  

new_data = [[i, next(indices[i], None)] for i in data]

result = [(lambda x:'NONE' if not x else x[0])([c['label'] for c in tokens if b and c['start'] <= b[0] and b[-1] <= c['end']]) for a, b in new_data]

输出:


['NONE', 'NONE', 'salutation', 'salutation', 'NONE', 'NONE', 'NONE', 'verb', 'NONE', 'NONE', 'NONE', 'NONE', 'NONE', 'NONE', 'NONE', 'size', 'NONE', 'NONE']

查看完整回答
反对 回复 2022-01-18
?
胡说叔叔

TA贡献1804条经验 获得超8个赞

目前我已经使用 HTMLParser 完成了这项工作:


from html.parser import HTMLParser

from tensorflow.keras.preprocessing.text import text_to_word_sequence


class HTML_tokenizer_labeller(HTMLParser):

  def __init__(self, annotations, *args, **kwargs):

    super(HTML_tokenizer_labeller, self).__init__(*args, **kwargs)

    self.tokens = []

    self.labels = []

    self.annotations = annotations


  def handle_starttag(self, tag, attrs):

    self.tokens.append(f'<{tag}>')

    self.labels.append('OTHER')


  def handle_endtag(self, tag):

    self.tokens.append(f'</{tag}>')

    self.labels.append('OTHER')


  def handle_data(self, data):

    print(f"getpos = {self.getpos()}")

    tokens = text_to_word_sequence(data)


    pos = self.getpos()[1]

    for annotation in annotations:

      if annotation['start'] <= pos <= annotation['end']:

        label = annotation['tag']

        break

    else: label = 'OTHER'


    self.tokens += tokens

    self.labels += [label] * len(tokens)


查看完整回答
反对 回复 2022-01-18
  • 2 回答
  • 0 关注
  • 160 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号