J'essaie d'obtenir les éléments d'un document HTML qui contiennent le modèle de texte suivant: #\S {11}
<h2> this is cool #12345678901 </h2>
Ainsi, le précédent correspondrait en utilisant:
soup('h2',text=re.compile(r' #\S{11}'))
Et les résultats seraient quelque chose comme:
[u'blahblah #223409823523', u'thisisinteresting #293845023984']
Je peux obtenir tout le texte qui correspond (voir la ligne ci-dessus). Mais je veux que l'élément parent du texte corresponde, donc je peux l'utiliser comme point de départ pour parcourir l'arborescence du document. Dans ce cas, je voudrais que tous les éléments h2 retournent, pas les correspondances de texte.
Des idées?
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
Tirages:
<h2>this is cool #12345678901</h2>
<h2>this is interesting #126666678901</h2>
<h2>this is blah #124445678901</h2>
Les opérations de recherche de BeautifulSoup fournissent [une liste de] BeautifulSoup.NavigableString
objets lorsque text=
est utilisé comme critère par opposition à BeautifulSoup.Tag
dans d'autres cas. Vérifiez le __dict__
pour voir les attributs mis à votre disposition. Parmi ces attributs, parent
est préféré à previous
à cause de changements dans 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
Avec bs4 (Beautiful Soup 4), la tentative du PO fonctionne exactement comme prévu:
from bs4 import BeautifulSoup
soup = BeautifulSoup("<h2> this is cool #12345678901 </h2>")
soup('h2',text=re.compile(r' #\S{11}'))
résultats [<h2> this is cool #12345678901 </h2>]
.