profundidad límite de tag.text

votos
0

No puedo hacerlo bien. BeautifulSoup4 es tan confuso.

Estoy tratando de arreglar las referencias de rebajas sin renderizar en el texto HTML. La expresión regular es:

REF = re.compile(r\[(?P<title>.+?)\]\[(?P<identifier>.*?)\])

Ya que al parecer BS4 usos matchcon expresiones regulares, hice la expresión regular con la más amplia

REF = re.compile(r.*\[(?P<title>.+?)\]\[(?P<identifier>.*?)\].*, re.DOTALL)

El objetivo es encontrar este tipo de cadenas y reemplazarlos con reales <a>enlaces, pero no si se encuentran en una <code>etiqueta (cualquiera que sea la profundidad). Tengo un mapeo para obtener la URL de la identifier.

[<code>title<code>][identifier]debe corresponder, pero <code>[title][identifier]</code>no debería.

Si la entrada es:

<p>[<code>title<code>][identifier]</p>

La salida debe ser:

<p><a id=identifier href=http://example.com><code>title<code></a></p>

Sin embargo, la siguiente entrada debe permanecer intacta:

<p><code>[title][identifier]</code></p>

He intentado lo siguiente:

tags = [tag.parent for tag in soup.find_all(text=REF) if not tag.find_parent(code)]

... pero faltaba etiquetas. He encontrado una explicación en este post: BeautifulSoup - Búsqueda por texto dentro de una etiqueta . Parece text(o el nuevo nombre string, aunque me pareció que el comportamiento a ser diferente) devolverá Nonecuando hay otras etiquetas en la etiqueta, es decir, la etiqueta <p>[<code>title<code>][identifier]</p>no será igualada.

También pensé en el puesto dio la solución:

tags = list(
    soup.find_all(
        lambda tag: tag.name != code and
                    not tag.find_parent(code) and
                    REF.search(tag.text)
    )
)

... pero ahora en vez de darme etiquetas cerca de las hojas, devuelve las etiquetas de raíz como <html>y <body>porque tag.textdevuelve el texto recursiva completa de todos los descendientes . Entonces, por supuesto, estas etiquetas de texto a juego contiene la expresión regular, pero dentro de <code>las etiquetas .

La mejor solución, creo, sería probar la expresión regular contra el texto de la etiqueta limitado a una cierta profundidad. Si la profundidad-1 texto de <p>[<code>title</code>][identifier]</p>es [ ][identifier]y profundidad-2 texto de la misma etiqueta es [<code>title</code>][identifier], a continuación, profundidad-2 es todo lo necesario.

¿Hay una manera de hacer eso? ¿O usted tiene alguna otra solución en mente? Pensé que tal vez podría repetir en todas las etiquetas de las hojas a la raíz, primero en amplitud, pero todavía tendrá el mismo problema con tag.textregresar el texto a todos los descendientes también.

Publicado el 19/03/2020 a las 22:00
fuente por usuario
En otros idiomas...                            

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more