2009-05-14 7 views
52

estoy tratando de obtener los elementos de un documento HTML que contiene el siguiente patrón de texto: # \ S {11}BeautifulSoup para encontrar una etiqueta HTML que contiene un texto determinado

<h2> this is cool #12345678901 </h2> 

Por lo tanto, la anterior coincidiría con:

soup('h2',text=re.compile(r' #\S{11}')) 

Y el resultado sería algo como:

[u'blahblah #223409823523', u'thisisinteresting #293845023984'] 

soy capaz de obtener todo el texto que m atches (ver la línea arriba). Pero quiero que el elemento padre del texto coincida, así que puedo usarlo como punto de partida para recorrer el árbol de documentos. En este caso, quisiera que regresen todos los elementos h2, no el texto coincida.

Ideas?

+3

En realidad, la restricción h2 se ignora de acuerdo con la documentación de BeautifulSoup: "Si usa texto, se ignorarán los valores que proporcione para el nombre y los argumentos de la palabra clave". – Rabarberski

+0

@Rabarberski No estoy seguro de cuál era la situación en 2010, pero [en 2012] (https://web.archive.org/web/20120427003845/http://www.crummy.com/software/BeautifulSoup/bs4/doc/ # the-text-argument) encuentra que usar 'text' (o' string' que lo reemplazó) no ignoraría ninguna otra restricción –

Respuesta

61
from BeautifulSoup import BeautifulSoup 
import re 

html_text = """ 
<h2>this is cool #12345678901</h2> 
<h2>this is nothing</h2> 
<h1>foo #126666678901</h1> 
<h2>this is interesting #126666678901</h2> 
<h2>this is blah #124445678901</h2> 
""" 

soup = BeautifulSoup(html_text) 


for elem in soup(text=re.compile(r' #\S{11}')): 
    print elem.parent 

Lienzo:

<h2>this is cool #12345678901</h2> 
<h2>this is interesting #126666678901</h2> 
<h2>this is blah #124445678901</h2> 
+0

¡Gracias! Es confuso que devolvió lo que parecía una lista de cadenas Unicode. Aprecio la ayuda. – sotangochips

+2

'.parent' fue increíble! Nunca pensé en ello. Gracias @nosklo. +1 –

+0

Si desea iterar el resultado de la búsqueda de inmediato, entonces es perfecto. De lo contrario, ¿qué tal una lista de comprensión como tal: [elem.parent para element in soup (text = re.compile (r '# \ S {11}'))] – peterb

12

BeautifulSoup operaciones de búsqueda entregan [] una lista de objetos cuando BeautifulSoup.NavigableStringtext= se utiliza como criterio en lugar de BeautifulSoup.Tag en otros casos. Compruebe el objeto __dict__ para ver los atributos puestos a su disposición. De estos atributos, parent se ve favorecida sobre previous debido a changes in BS4.

from BeautifulSoup import BeautifulSoup 
from pprint import pprint 
import re 

html_text = """ 
<h2>this is cool #12345678901</h2> 
<h2>this is nothing</h2> 
<h2>this is interesting #126666678901</h2> 
<h2>this is blah #124445678901</h2> 
""" 

soup = BeautifulSoup(html_text) 

# Even though the OP was not looking for 'cool', it's more understandable to work with item zero. 
pattern = re.compile(r'cool') 

pprint(soup.find(text=pattern).__dict__) 
#>> {'next': u'\n', 
#>> 'nextSibling': None, 
#>> 'parent': <h2>this is cool #12345678901</h2>, 
#>> 'previous': <h2>this is cool #12345678901</h2>, 
#>> 'previousSibling': None} 

print soup.find('h2') 
#>> <h2>this is cool #12345678901</h2> 
print soup.find('h2', text=pattern) 
#>> this is cool #12345678901 
print soup.find('h2', text=pattern).parent 
#>> <h2>this is cool #12345678901</h2> 
print soup.find('h2', text=pattern) == soup.find('h2') 
#>> False 
print soup.find('h2', text=pattern) == soup.find('h2').text 
#>> True 
print soup.find('h2', text=pattern).parent == soup.find('h2') 
#>> True 
+0

Para mí 'soup.find ('h2', texto = patrón) 'da la etiqueta directamente, no es necesario llamar a' .parent'. Además, la [documentación] (https://www.crummy.com/software/BeautifulSoup/bs4/doc/#the-string-argument) dice que puede combinar el parámetro 'string' (' text' en versiones anteriores) con argumentos que encuentran etiquetas. En este caso, BeautifulSoup devolverá la etiqueta – raffamaiden

0

Con bs4 (Beautiful Soup 4), el intento de la OP funciona exactamente igual que se esperaba:

from bs4 import BeautifulSoup 
soup = BeautifulSoup("<h2> this is cool #12345678901 </h2>") 
soup('h2',text=re.compile(r' #\S{11}')) 

vuelve [<h2> this is cool #12345678901 </h2>].

Cuestiones relacionadas