Usando BeautifulSoup para encontrar uma tag HTML que contém determinado texto
-
21-08-2019 - |
Pergunta
Eu estou tentando obter os elementos em um doc HTML que contêm o seguinte padrão de texto: # \ S {11}
<h2> this is cool #12345678901 </h2>
Assim, o anterior iria corresponder usando:
soup('h2',text=re.compile(r' #\S{11}'))
E o resultado seria algo como:
[u'blahblah #223409823523', u'thisisinteresting #293845023984']
eu sou capaz de obter todo o texto que partidas (veja a linha acima). Mas eu quero o elemento pai do texto para corresponder, para que eu possa usar isso como um ponto de partida para percorrer a árvore documento. Neste caso, eu quero todos os elementos h2 para voltar, e não os jogos de texto.
Idéias?
Solução
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
Prints:
<h2>this is cool #12345678901</h2>
<h2>this is interesting #126666678901</h2>
<h2>this is blah #124445678901</h2>
Outras dicas
operações de busca BeautifulSoup entregar [a lista de] BeautifulSoup.NavigableString
objetos quando text=
é usada como critério em oposição a BeautifulSoup.Tag
em outros casos. Verifique __dict__
do objeto para ver os atributos disponibilizados para você. Desses atributos, parent
é favorecido sobre previous
por causa muda em 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
Com BS4 (Bela Soup 4), a tentativa do OP funciona exatamente como o esperado:
from bs4 import BeautifulSoup
soup = BeautifulSoup("<h2> this is cool #12345678901 </h2>")
soup('h2',text=re.compile(r' #\S{11}'))
retornos [<h2> this is cool #12345678901 </h2>]
.