from example python beautifulsoup tree-traversal

python - example - Profundidad de primer recorrido en BeautifulSoup Parse Tree



from bs4 import beautifulsoup (2)

Creo que puedes usar el método "childGenerator" y utilizarlo recursivamente para analizar el árbol de forma DFT.

def recursiveChildren(x): if "childGenerator" in dir(x): for child in x.childGenerator(): name = getattr(child, "name", None) if name is not None: print "[Container Node]",child.name recursiveChildren(child) else: if not x.isspace(): #Just to avoid printing "/n" parsed from document. print "[Terminal Node]",x if __name__ == "__main__": soup = BeautifulSoup(your_data) for child in soup.childGenerator(): recursiveChildren(child)

Con "childGenerator" in dir(x) nos aseguramos de que un elemento sea un contenedor, los nodos de terminal como NavigableStrings no son contenedores y no contienen elementos secundarios.

Por ejemplo, HTML como:

<html> <ul> <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li> <li>Aliquam tincidunt mauris eu risus.</li> <li>Vestibulum auctor dapibus neque.</li> </ul> </html>

Este script imprime ...

[Container Node] ul [Container Node] li [Terminal Node] Lorem ipsum dolor sit amet, consectetuer adipiscing elit. [Container Node] li [Terminal Node] Aliquam tincidunt mauris eu risus. [Container Node] li [Terminal Node] Vestibulum auctor dapibus neque.

¿Hay alguna forma de hacer un DFT en un árbol de análisis BeautifulSoup? Intento hacer algo como empezar desde la raíz, generalmente, obtener todos los elementos secundarios y luego, para cada elemento secundario, obtener sus hijos, etc., hasta que llegue a un nodo terminal, en cuyo punto construiré mi camino de vuelta al árbol . El problema es que parece que no puedo encontrar un método que me permita hacer esto. Encontré el método findChildren pero parece que simplemente coloca toda la página en una lista varias veces con cada entrada subsiguiente que se reduce. Podría ser capaz de usar esto para hacer un recorrido, sin embargo, aparte de la última entrada en la lista, no parece que haya alguna forma de identificar las entradas como nodos de terminal o no. ¿Algunas ideas?


recursiveChildGenerator() ya hace eso:

soup = BeautifulSoup.BeautifulSoup(html) for child in soup.recursiveChildGenerator(): name = getattr(child, "name", None) if name is not None: print name elif not child.isspace(): # leaf node, don''t print spaces print child

Salida

Para la respuesta html from @ msalvadores :

html ul li Lorem ipsum dolor sit amet, consectetuer adipiscing elit. li Aliquam tincidunt mauris eu risus. li Vestibulum auctor dapibus neque. html

NOTA: html se imprime dos veces debido a que el ejemplo contiene dos etiquetas de apertura <html> .