BeautifulSoup - поиск последовательных (не иерархических) HTML-элементов - PullRequest
0 голосов
/ 08 мая 2018

Так что я занимаюсь разбором сайта, который не очень хорошо спроектирован. Элементы в действительности не имеют иерархической структуры.

Есть один огромный div, который имеет следующую структуру: куча вещей, которые мне не нужны, и затем следующая структура повторяется произвольное количество раз:

h4
p
ul
(
strong
ul
)

Где все, что в скобках, может повторяться любое количество раз.

Я хочу извлечь каждый экземпляр этого шаблона, но так как нет элемента, содержащего все из них, который я могу просто выбрать, у меня возникли проблемы. Похоже, мне нужна какая-то форма поиска по регулярным выражениям, так как есть порядок, но нет иерархии.

В качестве альтернативы, было бы неплохо извлечь все между каждым h4. Это возможно с BeautifulSoup?

Есть совет? BeautifulSoup даже то, что я хочу?

1 Ответ

0 голосов
/ 08 мая 2018
import bs4


def names(tags):
    return [t.name for t in tags]


def extract(soup):
    all_tags = [c for c in soup.div.children if isinstance(c, bs4.Tag)]

    groups = []
    i = 0
    while i < len(all_tags):
        group = all_tags[i:i + 3]
        if names(group) == ['h4', 'p', 'ul']:
            i += 3
            while True:
                extra = all_tags[i:i + 2]
                if names(extra) == ['strong', 'ul']:
                    group.extend(extra)
                    i += 2
                else:
                    break
            groups.append(group)
        else:
            i += 1
    return groups

# Demo:

print(extract(bs4.BeautifulSoup('''
<div>
    <p></p>

    <h4></h4>
    <p></p>
    <ul></ul>
    <strong></strong>
    <ul></ul>

    <span></span>
    <span></span>

    <h4></h4>
    <p></p>
    <ul></ul>

    <h4></h4>
    <p></p>

    <h4></h4>
    <p></p>
    <ul></ul>
    <strong></strong>
    <ul></ul>
    <strong></strong>
    <ul></ul>

    <span></span>
    <span></span>
</div>
''', 'lxml')))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...