BeautifulSoup - 查找顺序(非分层)html元素

时间:2018-05-07 23:06:29

标签: python web-scraping beautifulsoup

所以我正在解析一个设计不够精良的网站。元素并不是真正的层次结构。

有一个巨大的div,它具有以下结构:一堆我不关心的东西,然后以下结构重复了任意次:

h4
p
ul
(
strong
ul
)

括号之间的所有内容都可以重复多次。

我想提取这个模式的每个实例,但由于没有包含所有这些模式的元素我可以选择,我遇到了麻烦。看起来我需要某种形式的正则表达式元素搜索,因为它有顺序但没有层次结构。

或者,在每个h4之间提取所有内容都没问题。这对BeautifulSoup有用吗?

有什么建议吗? BeautifulSoup甚至是我想要的吗?

1 个答案:

答案 0 :(得分:-1)

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')))