2010-08-17 15 views
11

He estado jugando con BeautifulSoup, que es genial. Mi objetivo final es intentar obtener el texto de una página. Solo estoy tratando de obtener el texto del cuerpo, con un caso especial para obtener los atributos de título y/o alt de las etiquetas <a> o <img>.¿Cómo puedo quitar etiquetas de comentarios de HTML usando BeautifulSoup?

hasta ahora tengo este EDITED & UPDATED CURRENT CODE:

soup = BeautifulSoup(page) 
comments = soup.findAll(text=lambda text:isinstance(text, Comment)) 
[comment.extract() for comment in comments] 
page = ''.join(soup.findAll(text=True)) 
page = ' '.join(page.split()) 
print page 

1) ¿Qué sugiere la mejor manera para que mi caso especial de no excluir aquellos atributos de las dos etiquetas que se enumeran más arriba? Si es demasiado complejo para hacer esto, no es tan importante como hacer # 2.

2) Me gustaría quitar las etiquetas <!-- --> y todo lo que hay entre ellas. ¿Cómo voy a hacer eso?

QUESTION EDIT @jathanism: Estas son algunas de las etiquetas de comentarios que he tratado de despojar, pero siguen siendo, aun cuando utilizo el ejemplo

<!-- Begin function popUp(URL) { day = new Date(); id = day.getTime(); eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=300,height=330,left = 774,top = 518');"); } // End --> 
<!-- var MenuBar1 = new Spry.Widget.MenuBar("MenuBar1", {imgDown:"SpryAssets/SpryMenuBarDownHover.gif", imgRight:"SpryAssets/SpryMenuBarRightHover.gif"}); //--> <!-- var MenuBar1 = new Spry.Widget.MenuBar("MenuBar1", {imgDown:"SpryAssets/SpryMenuBarDownHover.gif", imgRight:"SpryAssets/SpryMenuBarRightHover.gif"}); //--> <!-- var whichlink=0 var whichimage=0 var blenddelay=(ie)? document.images.slide.filters[0].duration*1000 : 0 function slideit(){ if (!document.images) return if (ie) document.images.slide.filters[0].apply() document.images.slide.src=imageholder[whichimage].src if (ie) document.images.slide.filters[0].play() whichlink=whichimage whichimage=(whichimage<slideimages.length-1)? whichimage+1 : 0 setTimeout("slideit()",slidespeed+blenddelay) } slideit() //--> 
+0

¿Existe un documento fuente que se está utilizando como un caso de prueba? Sería de gran ayuda si pudiera proporcionar algo que tenga en mente como base de comparación. – jathanism

+0

Fuente añadida para jugar. – Nathan

Respuesta

2

todavía estoy tratando de averiguar por qué no encuentra y las etiquetas de banda como esta: <!-- //-->. Esas barras invertidas causan que se pasen por alto ciertas etiquetas.

Esto puede ser un problema con el analizador SGML subyacente: vea http://www.crummy.com/software/BeautifulSoup/documentation.html#Sanitizing%20Bad%20Data%20with%20Regexps. Puede evitarla usando una expresión regular markupMassage - directamente de los documentos:

import re, copy 

myMassage = [(re.compile('<!-([^-])'), lambda match: '<!--' + match.group(1))] 
myNewMassage = copy.copy(BeautifulSoup.MARKUP_MASSAGE) 
myNewMassage.extend(myMassage) 

BeautifulSoup(badString, markupMassage=myNewMassage) 
# Foo<!--This comment is malformed.-->Bar<br />Baz 
+1

Esta es una pregunta difícil y parece ser una buena solución. Es triste que todavía termine usando regex para analizar HTML. Estúpida expresión regular! – jathanism

+0

OK, trabajaré en re.compile para detectar los comentarios desordenados que enumeré. Sin embargo, necesito repasar mis expresiones regex. blech. – Nathan

+0

@jathanism - BeautifulSoup usa varias expresiones regulares internamente para pulir el HTML antes de que se lo 'sgmllib'. No es bonito, pero tampoco es Lovecraftian. – katrielalex

53

Directamente desde el documentation for BeautifulSoup, se puede pelar fácilmente los comentarios (o nada) utilizando extract():

from BeautifulSoup import BeautifulSoup, Comment 
soup = BeautifulSoup("""1<!--The loneliest number--> 
         <a>2<!--Can be as bad as one--><b>3""") 
comments = soup.findAll(text=lambda text:isinstance(text, Comment)) 
[comment.extract() for comment in comments] 
print soup 
# 1 
# <a>2<b>3</b></a> 
+0

No sé por qué no vi eso. ¡Gracias por despertarme! – Nathan

+5

Agradable. Pero parece muy complicado hacer una lista de comprensión con efectos secundarios: p. ¿Qué tal 'map (lambda x: x.extract(), comments)'? – katrielalex

+0

Todavía estoy tratando de descubrir por qué no encuentra y tira etiquetas como esta '' Esas barras invertidas hacen que se pasen por alto ciertas etiquetas – Nathan

Cuestiones relacionadas