wake-up-neo.net

Verwenden Sie BeautifulSoup, um ein HTML-Tag zu finden, das bestimmten Text enthält

Ich versuche, die Elemente in einem HTML-Dokument abzurufen, die das folgende Textmuster enthalten: #\S {11}

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

Der vorherige würde also mit folgendem übereinstimmen:

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

Und die Ergebnisse wären ungefähr so:

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

Ich kann den gesamten Text abrufen, der übereinstimmt (siehe Zeile oben). Ich möchte jedoch, dass das übergeordnete Element des Texts übereinstimmt, damit ich es als Ausgangspunkt für das Durchlaufen des Dokumentbaums verwenden kann. In diesem Fall möchte ich, dass alle h2-Elemente zurückgegeben werden und nicht der Text übereinstimmt.

Ideen?

60
sotangochips
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

Drucke:

<h2>this is cool #12345678901</h2>
<h2>this is interesting #126666678901</h2>
<h2>this is blah #124445678901</h2>
69
nosklo

BeautifulSoup-Suchvorgänge liefern [eine Liste von] BeautifulSoup.NavigableString Objekte, wenn text= wird als Kriterium verwendet im Gegensatz zu BeautifulSoup.Tag in anderen Fällen. Überprüfen Sie das Objekt __dict__, um die Ihnen zur Verfügung gestellten Attribute anzuzeigen. Von diesen Attributen wird parent wegen Änderungen in BS4 gegenüber previous bevorzugt.

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
19
Bruno Bronosky

Mit bs4 (Beautiful Soup 4) funktioniert der Versuch des OP genau wie erwartet:

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

kehrt zurück [<h2> this is cool #12345678901 </h2>].

2
T.C. Proctor