【问题标题】:Checking children for tags in Beautiful Soup 4 with python使用 python 在 Beautiful Soup 4 中检查孩子的标签
【发布时间】:2019-06-29 18:28:24
【问题描述】:

我正在使用 BeautifulSoup 4 和 python 来解析一些 HTML。代码如下:

from bs4 import BeautifulSoup as bs
html_doc = '<p class="line-spacing-double" align="center">IN <i>THE </i><b>DISTRICT</b> COURT OF {county} COUNTY\nSTATE OF OKLAHOMA</p>'

soup = bs(html_doc, 'html.parser')
para = soup.p

for child in soup.p.children:
    print (child)

结果是:

IN
<i>THE </i>
<b>DISTRICT</b>
 COURT OF {county} COUNTY
STATE OF OKLAHOMA

这一切都说得通。我想要做的是遍历结果,如果我找到&lt;i&gt;&lt;b&gt; 然后对它们做一些不同的事情。当我尝试以下操作时,它不起作用:

for child in soup.p.children:
    if child.findChildren('i'):
        print('italics found')

错误是因为第一个返回的孩子是一个字符串,我正在尝试搜索一个孩子标签,而 BS4 已经知道没有孩子在场。

所以我修改了代码来检查孩子是否是一个字符串,如果是,不要尝试对其采取任何操作,只需将其打印出来。

for child in soup.p.children:
    if isinstance(child, str):
        print(child)
    elif child.findAll('i'):
        for tag in child.findAll('i'):
            print(tag)

这个最新代码的结果:

IN
 COURT OF {county} COUNTY
STATE OF OKLAHOMA

当我遍历结果时,我需要能够检查结果中的标签,但我似乎无法弄清楚如何。我认为这应该很简单,但我很难过。

编辑:

回应 jacalvo:

如果我跑步

for child in soup.p.children:
    if child.find('i'):
        print(child)

仍然无法从 HTML 代码中打印出第 2 行和第 3 行

编辑:

for child in soup.p.children:
    if isinstance(child, str):
        print(child)
    else:
        print(child.findChildren('i', recursive=False))

这导致:

IN
[]
[]
 COURT OF {county} COUNTY
STATE OF OKLAHOMA

【问题讨论】:

  • find('i')代替findChildren()怎么样?
  • p = soup.select_one('p') 然后p.select('i, b')
  • jacalvo - 我需要编写代码(这在 cmets 中很烂),所以我通过对原始帖子的编辑回复了您。
  • @Andrej Kesely - 这适用于查找 &lt;i&gt;&lt;b&gt; 标签,但我确实需要遍历所有标签,而不仅仅是找到这些标签。它们在 HTML 中的位置对我需要做的事情很重要。

标签: python beautifulsoup


【解决方案1】:

这是您尝试使用标签“做一些不同的事情”的示例吗?在问题中提供完整所需输出的样本将有所帮助:

from bs4 import BeautifulSoup as bs

html_doc = '<p class="line-spacing-double" align="center">IN <i>THE</i> <b>DISTRICT</b> COURT OF {county} COUNTY\nSTATE OF OKLAHOMA</p>'
soup = bs(html_doc, 'html.parser')
para = soup.p

for child in para.children:
    if child.name == 'i':
        print(f'*{child.text}*',end='')
    elif child.name == 'b':
        print(f'**{child.text}**',end='')
    else:
        print(child,end='')

输出:

IN *THE* **DISTRICT** COURT OF {county} COUNTY
STATE OF OKLAHOMA

【讨论】:

  • 这正是我所需要的。我什至没有想过孩子的名字是现在的标签,但事后看来这是完全有道理的。
【解决方案2】:

使用findChildren(),然后用if条件检查子名。

from bs4 import BeautifulSoup as bs
html_doc = '<p class="line-spacing-double" align="center">IN <i>THE </i><b>DISTRICT</b> COURT OF {county} COUNTY\nSTATE OF OKLAHOMA</p>'

soup = bs(html_doc, 'html.parser')

for child in soup.find('p').findChildren(recursive=False) :
    if child.name=='i':
        print(child)
    if child.name=='b':
        print(child)

输出:

<i>THE </i>
<b>DISTRICT</b>

【讨论】:

    【解决方案3】:
        from bs4 import BeautifulSoup as bs
    
        html_doc = '<p class="line-spacing-double" align="center">IN <i>THE </i><b>DISTRICT</b> COURT OF {county} ' \
                   'COUNTY\nSTATE OF OKLAHOMA</p> '
    
        soup = bs(html_doc, 'html.parser')
        paragraph = soup.p
    
        # all tags dynamically gotten
        tags = [tag.name for tag in soup.find_all()]
    
        for child in paragraph.children:
            if child.name in tags:
                print('{0}'.format(child))  # or child.text
            else:
                print(child)
    

    输出

        IN 
        <i>THE </i>
        <b>DISTRICT</b>
         COURT OF {county} COUNTY
        STATE OF OKLAHOMA
    

    【讨论】:

    • 我将通过编辑问题来回复您,以便我可以发布我运行的代码,其中包含您的 recursive=False
    • 我即将求助于正则表达式 :) HTML 解析的最大罪过 LOL
    • 天啊!这是一个极端的决定......(:也许我不明白你的想法,但我用更多的斜体和粗体更新了代码,并将它们全部打印在两个不同的列表中,这样你就可以在之后进行进一步的操作
    • 这会找到所有的斜体和粗体,但它不允许我像孩子一样遍历文本。我需要遍历它们的原因是我正在转换为 DOCX,并且我需要使用 python-docx 来 add_run() 并且与段落中的其他文本相比,这需要一定的顺序。
    • 哦!当我在 xlsxwriter 中使用 worksheet.write_rich_string 制作一个巨大的动态富文本时,我遇到了类似的问题......顺序很重要。所以,我猜在这个过程中你需要孩子、标签和文本
    猜你喜欢
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多