6
html = """
...
<tt class="descname">all</tt>
<big>(</big>
<em>iterable</em>
<big>)</big>
<a class="headerlink" href="#all" title="Permalink to this definition">¶</a>
...
"""

我想big在第一次出现a标签之前获取起始标签之间的所有文本。这意味着如果我举这个例子,那么我必须得到(iterable)一个字符串。

4

4 回答 4

6

一种迭代方法。

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
于 2012-08-04T14:25:40.153 回答
4

我会避免 nextSibling,因为从您的问题来看,您希望包含直到 next 的所有内容<a>,无论它是在兄弟元素、父元素还是子元素中。

因此,我认为最好的方法是找到作为下一个<a>元素的节点并递归循环直到那时,添加遇到的每个字符串。如果您的 HTML 与示例有很大不同,您可能需要整理以下内容,但这样的事情应该可以工作:

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
于 2012-08-04T13:59:44.323 回答
1

你可以这样做:

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

有关详细信息,请从此处查看使用 BeautifulSoup 遍历的 dom

于 2012-08-04T13:47:39.750 回答
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)'
于 2012-08-04T13:11:30.300 回答