2012-06-30 27 views
5

¿Cómo se hace para analizar una página HTML con texto libre, listas, tablas, encabezados, etc., en oraciones?Analizando HTML en oraciones: ¿cómo manejar tablas/listas/encabezados/etc.?

Tome this wikipedia page por ejemplo. Hay/son:

Después de jugar un poco con la pitón NLTK, quiero poner a prueba todos estos diferentes métodos de anotación de corpus (desde http://nltk.googlecode.com/svn/trunk/doc/book/ch11.html#deciding-which-layers-of-annotation-to-include):

  • Tokenización de palabras: la forma ortográfica del texto no identifica inequívocamente sus tokens. Una versión tokenizada y normalizada, además de la versión ortográfica convencional, puede ser un recurso muy conveniente.
  • Segmentación de oraciones: Como vimos en el Capítulo 3, la segmentación de oraciones puede ser más difícil de lo que parece. Algunos corpora, por lo tanto, usan anotaciones explícitas para marcar la segmentación de oraciones.
  • Segmentación de párrafo: Los párrafos y otros elementos estructurales (encabezados, capítulos, etc.) pueden anotarse explícitamente.
  • Parte del discurso: la categoría sintáctica de cada palabra en un documento.
  • Estructura sintáctica: Estructura de árbol que muestra la estructura constituyente de una oración.
  • Semántica superficial: anotaciones de entidades nombradas y correferencia, etiquetas de roles semánticos.
  • diálogo y el discurso: diálogo acto etiquetas, estructura retórica

Una vez que se rompe un documento en frases parece bastante sencillo. ¿Pero cómo se trata de descifrar algo como el HTML de esa página de Wikipedia? Estoy muy familiarizado con el uso de analizadores HTML/XML y recorriendo el árbol, y he intentado quitar las etiquetas HTML para obtener el texto plano, pero debido a que falta la puntuación después de eliminar HTML, NLTK no analiza elementos como las celdas de la tabla, o incluso listas, correctamente.

¿Existe alguna mejor práctica o estrategia para analizar esas cosas con NLP? ¿O solo tienes que escribir manualmente un analizador específico para esa página individual?

Simplemente buscando algunos indicadores en la dirección correcta, realmente quiero probar este NLTK!

+0

¿Ha intentado utilizar Punkt (está implementado en NLTK) en el texto eliminado para ver si eso lo lleva a alguna parte? – dmh

+1

Mi observación informal es que los analizadores sintácticos generalmente son malos para manejar y representar texto de visualización (en lugar de ejecutar prosa). Si encuentra o diseña una buena solución, ¡síganos aquí! – tripleee

Respuesta

1

Parece que estás eliminando todo el código HTML y generando un documento plano, lo que confunde al analizador ya que las piezas sueltas están pegadas. Dado que tiene experiencia con XML, le sugiero mapear sus entradas a una estructura XML simple que mantiene las piezas separadas. Puede hacerlo de la manera más simple que desee, pero quizás quiera retener cierta información. Por ejemplo, puede ser útil marcar títulos, encabezados de secciones, etc. como tales. Cuando tenga un árbol XML viable que mantenga los fragmentos separados, use XMLCorpusReader para importarlo en el universo NLTK.

1

Tuve que escribir reglas específicas para los documentos XML que estaba analizando.

Lo que hice fue hacer un mapeo de las etiquetas html en los segmentos. Este mapeo se basó en estudiar varios documentos/páginas y determinar qué representan las etiquetas html. Ej. <h1> es un segmento de frase; <li> son párrafos; <td> son tokens

Si desea trabajar con XML, puede representar las nuevas asignaciones como etiquetas. Ej. <h1> a <frase>; <li> a < párrafo >; <td> a < símbolo >

Si desea trabajar en texto plano, puede representar las asignaciones como un conjunto de caracteres (ej. [PHRASESTART] [PHRASEEND]), al igual que el etiquetado POS o EOS.

0

Puede usar herramientas como python-goose que tiene como objetivo extraer artículos de páginas html.

De lo contrario, formuló la siguiente pequeño programa que da clase de buenos resultados:

from html5lib import parse 


with open('page.html') as f: 
    doc = parse(f.read(), treebuilder='lxml', namespaceHTMLElements=False) 

html = doc.getroot() 
body = html.xpath('//body')[0] 


def sanitize(element): 
    """Retrieve all the text contained in an element as a single line of 
    text. This must be executed only on blocks that have only inlines 
    as children 
    """ 
    # join all the strings and remove \n 
    out = ' '.join(element.itertext()).replace('\n', ' ') 
    # replace multiple space with a single space 
    out = ' '.join(out.split()) 
    return out 


def parse(element): 
    # those elements can contain other block inside them 
    if element.tag in ['div', 'li', 'a', 'body', 'ul']: 
     if element.text is None or element.text.isspace(): 
      for child in element.getchildren(): 
       yield from parse(child) 
     else: 
      yield sanitize(element) 
    # those elements are "guaranteed" to contains only inlines 
    elif element.tag in ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']: 
     yield sanitize(element) 
    else: 
     try: 
      print('> ignored', element.tag) 
     except: 
      pass 


for e in filter(lambda x: len(x) > 80, parse(body)): 
    print(e) 
0

Como alexis contestado, python-goose puede ser una buena opción.

También hay HTML Sentence Tokenizer, una (nueva) biblioteca que tiene como objetivo resolver este problema exacto. Su sintaxis es muy simple. En una línea, parsed_sentences = HTMLSentenceTokenizer().feed(example_html_one), puede obtener las oraciones en una página HTML almacenada en la matriz parsed_sentences.