2012-08-04 17 views

Antwort

3

Ich würde nextSibling vermeiden, wie aus Ihrer Frage, Sie wollen alles umfassen, bis die nächste <a>, unabhängig davon, ob das in einem Geschwister-, Eltern- oder Kindelement ist.

Daher denke ich, der beste Ansatz ist es, den Knoten zu finden, der das nächste <a> Element und Schleife rekursiv ist, bis jeder String als angetroffen. Möglicherweise müssen Sie die unten aufzuräumen, wenn Ihre HTML sehr unterschiedlich von der Probe ist, aber so etwas wie dies funktionieren sollte:

from bs4 import BeautifulSoup 
#by taking the `html` variable from the question. 
html = BeautifulSoup(html) 
firstBigTag = html.find_all('big')[0] 
nextATag = firstBigTag.find_next('a') 
def loopUntilA(text, firstElement): 
    text += firstElement.string 
    if (firstElement.next.next == nextATag):    
     return text 
    else: 
     #Using double next to skip the string nodes themselves 
     return loopUntilA(text, firstElement.next.next) 
targetString = loopUntilA('', firstBigTag) 
print targetString 
+0

ja, genau, ich will alles bis zum nächsten Tag "a" einschließen und es kann eine beliebige Anzahl von Tags, Texten zwischen dem ersten "großen" Tag und dem ersten "a" -Tag geben –

0
>>> from BeautifulSoup import BeautifulSoup as bs 
>>> parsed = bs(html) 
>>> txt = [] 
>>> for i in parsed.findAll('big'): 
...  txt.append(i.text) 
...  if i.nextSibling.name != u'a': 
...   txt.append(i.nextSibling.text) 
... 
>>> ''.join(txt) 
u'(iterable)' 
+0

'nextiSbling' kann nicht verwendet werden, da ich jeden Text bis zum ersten Auftreten von Tag enthalten sein soll‚a‘ –

1

Sie können wie folgt tun:

from BeautifulSoup import BeautifulSoup 
html = """ 
<tt class="descname">all</tt> 
<big>(</big> 
<em>iterable</em> 
<big>)</big> 
<a class="headerlink" href="test" title="Permalink to this definition"></a> 
""" 
soup = BeautifulSoup(html) 
print soup.find('big').nextSibling.next.text 

Einzelheiten prüfen dom mit BeautifulSoup durchqueren von here

+0

Das gibt„iterable“statt„(abzählbaren)“ – anotherdave

5

Ein iterativer Ansatz.

from BeautifulSoup import BeautifulSoup as bs 
from itertools import takewhile, chain 

def get_text(html, from_tag, until_tag): 
    soup = bs(html) 
    for big in soup(from_tag): 
     until = big.findNext(until_tag) 
     strings = (node for node in big.nextSiblingGenerator() if getattr(node, 'text', '').strip()) 
     selected = takewhile(lambda node: node != until, strings) 
     try: 
      yield ''.join(getattr(node, 'text', '') for node in chain([big, next(selected)], selected)) 
     except StopIteration as e: 
      pass 

for text in get_text(html, 'big', 'a'): 
    print text 
Verwandte Themen