Utilizzando BeautifulSoup per trovare un tag HTML che contiene un determinato testo
-
21-08-2019 - |
Domanda
Sto cercando di ottenere gli elementi di un documento HTML che contiene il seguente schema di testo: # \ S {11}
<h2> this is cool #12345678901 </h2>
Quindi, la 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 corrisponde (vedi riga sopra). Ma io voglio l'elemento principale del testo da abbinare, in modo da poter utilizzare che come punto di partenza per attraversare l'albero del documento. In questo caso, vorrei tutti gli elementi h2 per tornare, non il testo corrisponde.
idee?
Soluzione
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>
Altri suggerimenti
BeautifulSoup offrono [un elenco di oggetti] BeautifulSoup.NavigableString
quando text=
viene utilizzato come criterio al contrario di BeautifulSoup.Tag
in altri casi. Controllare l'oggetto del __dict__
per vedere gli attributi reso disponibile a voi. Di questi attributi, parent
è favorita rispetto previous
a causa di modifiche 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
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}'))
ritorna [<h2> this is cool #12345678901 </h2>]
.