2009-05-14 13 views
52

Sto cercando di ottenere gli elementi di un documento HTML che contiene il seguente schema di testo: # \ S {11}Utilizzando BeautifulSoup per trovare un tag HTML che contiene un determinato testo

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

Così, il precedente sarebbe partita utilizzando:

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

E i risultati sarebbe qualcosa di simile:

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

sono in grado di ottenere tutto il testo che m atches (vedi riga sopra). Ma voglio che l'elemento genitore del testo corrisponda, quindi posso usarlo come punto di partenza per attraversare l'albero dei documenti. In questo caso, vorrei che restituissero tutti gli elementi h2, non le corrispondenze del testo.

Idee?

+3

In realtà, la restrizione h2 viene ignorata in base alla documentazione di BeautifulSoup: "Se si utilizza il testo, tutti i valori forniti per il nome e gli argomenti delle parole chiave vengono ignorati." – Rabarberski

+0

@Rabarberski Non sono sicuro di quale fosse la situazione nel 2010, ma [entro il 2012] (https://web.archive.org/web/20120427003845/http://www.crummy.com/software/BeautifulSoup/bs4/doc/ # the-text-argument) trova che usare 'text' (o' stringa' che lo ha sostituito) non ignorerebbe altre restrizioni –

risposta

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 

Stampe:

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

Grazie! È confuso che sia tornato quello che sembrava un elenco di stringhe Unicode. Apprezzo l'aiuto. – sotangochips

+2

'.parent' è stato fantastico! Non ci avevo mai pensato. Grazie a @nosklo. +1 –

+0

Se vuoi ripetere immediatamente l'output dalla ricerca, allora è perfetto. Altrimenti, per quanto riguarda la comprensione di una lista come tale: [elem.parent per l'elemento in zuppa (text = re.compile (r '# \ S {11}'))] – peterb

12

BeautifulSoup operazioni di ricerca offrono [] un elenco di oggetti quando BeautifulSoup.NavigableStringtext= viene utilizzato come criterio in contrasto con BeautifulSoup.Tag in altri casi. Controlla l'oggetto __dict__ per vedere gli attributi resi disponibili. Di questi attributi, parent è preferito su previous a causa di 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

Per me 'soup.find ('h2', text = pattern) 'dà direttamente il tag, non c'è bisogno di chiamare' .parent'. Anche la [documentazione] (https://www.crummy.com/software/BeautifulSoup/bs4/doc/#the-string-argument) dice che è possibile combinare il parametro 'string' (' testo' nelle versioni precedenti) con argomenti che trovano i tag. In questo caso, BeautifulSoup restituirà il tag – raffamaiden

0

Con BS4 (Beautiful Soup 4), il tentativo del PO funziona esattamente come previsto:

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

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

Problemi correlati