Вопрос по python, beautifulsoup, html-parsing – Как получить весь текст между двумя указанными тегами, используя BeautifulSoup?

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   ответа
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)'
nextiSbling не может быть использован, так как я хочу включить каждый текст до первого вхождения тега 'a'; Amit Yadav
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 отВот

Это возвращает & quot; повторяемость & quot; а не «(повторяемый)»
4

так как из вашего вопроса вы хотите включить все до следующего<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
да, именно, я хочу включить все до следующего тега "a"; и между первым «большим» может быть любое количество тегов и текстов; тег и первый 'a'; тег Amit Yadav
5

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

Похожие вопросы