Extraiga una cadena de varias líneas de un archivo HTML usando etiquetas específicas

Extraiga una cadena de varias líneas de un archivo HTML usando etiquetas específicas

Necesito extraer la cadena que comienza con la etiqueta <span class="style530">y termina con </span>la etiqueta.

Utilicé el comando sed pero no obtuve el resultado deseado. A continuación se muestra un código de muestra:

<strong>
-
<span class="style530">
AA - 
This
is my
First
Heading</span></strong><br>
<span class="style530">
<strong>
*Some
text,*
<strong>
*text*</strong>, 
*text*
<strong>
*text*</strong>: 
<br>
<span class="style530">
<strong>
- This 
is my
Second Heading</strong></span><br>
<span class="style530">
<strong>
*Some
text,*
<strong>
*text*</strong>, 
*Here
is some
text.*
<strong>*text*</strong>: 
*Here is 
some
text*.<br>
<br>
<strong>
-
<span class="style530">
- This is
my Third
Heading</span></strong><br>

La salida debería ser como:

 AA - This is my First Heading
 - This is my Second Heading
 - This is my Third Heading

¡Gracias!

Respuesta1

Regex no es realmente capaz de analizar HTML por completo.

Hay una herramienta de línea de comando llamadaXidelque le permite usar selectores XPath o CSS para extraer los bits que desea.

Algo como esto cumpliría con su requisito declarado:

./xidel test.html --extract '//span[@class="style530"]' --output-format bash

Pero tenga en cuenta que esto devuelve más que el resultado requerido ya que tiene uno sin cerrar.<span class="style530">

Respuesta2

Utilice HTMLParser para tales acciones:

#!/usr/bin/python
# vim: set fileencoding=utf8 :
# (c) fazie

from HTMLParser import HTMLParser
import re
import sys

class MyParser(HTMLParser):
    inside_span = False

    def __init__(self,file):
        HTMLParser.__init__(self)
        f = open(file)
        self.feed(f.read())

    def handle_starttag(self,tag,attrs):
        if tag == 'span':
            for name,value in attrs:
                if name=='class' and value=='style530':
                    self.inside_span=True

    def handle_data(self,data):
        data = data.strip(' \t\r\n')
        if data != "":
            if self.inside_span:
                data = re.sub('\n',' ',data)
                data = re.sub('\s\s+',' ',data)
                print data

    def handle_endtag(self,tag):
        if tag == 'span':
            self.inside_span=False

MyParser(sys.argv[1])

Ejecutarlo:

python myparser.py inputfile.html

Respuesta3

Puedes probar algo como lo siguiente.

awk -vRS='<' '
  inside || /^span[^>]*class="style530"/ {
    inside = 1
    if (/^span/)
      n++
    else if (/^\/span>/ && !--n) {
      $0="/span>\n"
      inside=0
    }
    printf "<%s", $0
  }' file.html | sed '/^</ d' | grep -v ">$"

Sin embargo, no es recomendable extraer utilizando encabezados HTML. Por favor miraaquípor qué no deberías analizar páginas HTML. Le sugiero que utilice curly w3melimine los encabezados HTML, después de lo cual el análisis será un poco más sencillo.

Respuesta4

Para extracciones simples de textos xml/html me gusta usar xidel conSelectores CSS.

En este ejemplo, para seleccionar todos spanlos elementos con el atributo classque contiene la palabra style530, podemos usar

xidel --css span.style530 --xml

xideltiene muchas opciones. La entrada proporcionada por la pregunta es un poco ruidosa. En situaciones menos ruidosas, --xmlpodemos obtener algo como

<xml>
  <span class="style530">case 1 </span>
  <span class="menu style530 otherclass">case 2 </span>
  ...
</xml>

información relacionada