使用 Beautiful Soup 解析 HTML 时,有时子标签不存在

问题描述 投票:0回答:1

使用 Beautiful Soup,我正在开发一个非常标准的程序,它可以解析 HTML 并根据 CSS 元素检索数据。我遇到的问题是,当我以原始形式检索 CSS 标签时,存在一些我无法调用的标签。

我以前从未遇到过这种情况。

图片

查看图片:我正在寻找的元素是黄色和红色标签中的绿色项目,但我只获取红色框中的元素。就好像黄色框不存在一样。

HTML 在这里:

<div style="padding-left: 30px">
  <h3 class="section_title"><span class="toggler" id="REG_TAG_AUDIO_MESSAGE_GIA_CNFG">[-]</span><span style="font-size: 10pt; font-weight: normal;">REG_TAG_AUDIO_MESSAGE_GIA_CNFG</span></h3><div class="canhide collapsable" style=""><div class="infoTable" style="padding-left: 30px">
  <table>
    <tbody><tr class="grayUnhidden"><th>Name</th><th>Value</th><th>Type</th><th>Type Description</th><th>Traceability</th><th>Config Note</th></tr>
    <tr class="odd"><td style="width: 15%;">queue_behavior</td><td>0x00000021 (IOP_AUD_BIT_PRIORITY_FIFO, IOP_AUD_BIT_INTERRUPT_NONE)</td><td>IOP_aud_queue_behavior_t32</td><td>audio queue behavior</td><td></td><td></td></tr>
    <tr class="odd"><td style="width: 15%;">gma_info.gma_model</td><td>IOP_AUD_CFG_GMA_36</td><td>IOP_audio_gma_model_t8</td><td>GMA model used in airframe</td><td></td><td></td></tr>
    <tr class="odd"><td style="width: 15%;">gma_info.gma_quantity</td><td>IOP_AUD_CFG_ONE_GMA_INSTALL</td><td>IOP_audio_gma_quantity_t8</td><td>number of GMAs used</td><td></td><td></td></tr>
    <tr class="odd"><td style="width: 15%;">gma_info.gma_audio_path</td><td>IOP_AUD_CFG_GMA_GIA6XW_DIGITAL</td><td>IOP_audio_gma_path_t8</td><td>GMA-GIA audio path type</td><td></td><td></td></tr>
    <tr class="odd"><td style="width: 15%;">gma_info.gma_path_fail</td><td>IOP_AUD_CFG_GMA_FAIL_CLASSIC_DIG_FAULT</td><td>IOP_audio_gma_path_fail_t8</td><td>audio path failure behavior</td><td></td><td></td></tr></tbody></table></div><div style="padding-left: 30px">
    <h3 class="section_title"><span class="toggler">[-]</span><span>clip_volume[0]: IOP_AUD_DB_CLIP_DA40_ALERT</span></h3><div class="canhide collapsable" style=""><div class="infoTable" style="padding-left: 30px">
    <table>
      <tbody><tr class="grayUnhidden"><th>Name</th><th>Value</th><th>Type</th><th>Type Description</th><th>Traceability</th><th>Config Note</th></tr>
      <tr class="odd"><td style="width: 15%;">database_clip_id</td><td>IOP_AUD_DB_CLIP_DA40_ALERT</td><td>IOP_audio_clip_t32</td><td>database clip id</td><td></td><td></td></tr>
      <tr class="odd"><td style="width: 15%;">attenuation</td><td>9</td><td>uint8</td><td>attenuation value</td><td></td><td></td></tr></tbody></table></div></div></div><div style="padding-left: 30px">

当我运行以下命令时:

fifth_level = child.div.table.find_all('tr', class_='odd')
    for l in fifth_level:
        print(l)

打印

l
让我得到这个:

<tr class="odd"><td style="width: 15%;">database_clip_id</td><td>IOP_AUD_DB_CLIP_DA40_ALERT</td><td>IOP_audio_clip_t32</td><td>database clip id</td><td></td><td></td></tr>

<tr class="odd"><td style="width: 15%;">attenuation</td><td>9</td><td>uint8</td><td>attenuation value</td><td></td><td></td></tr>

对我来说,很明显有两个不同的元素,每个元素都有自己的后代集。我遇到的问题是,我想要嵌套在其中的元素之一的文本。但是当我呼吁每个人使用此代码时:

fifth_level = child.div.table.find_all('tr', class_='odd')
for l in fifth_level:
    # print(l)
    ltitle = l.td. text
    value = l.td.next_sibling.text
    print('TITLE:' + str(title) + '\t Name: ' + str(ltitle) + '\t VALUE: ' + str(value))

我得到这个结果:

TITLE:clip_volume[0]: IOP_AUD_DB_CLIP_DA40_ALERT     Name: attenuation   VALUE: 9

当我期待这个结果时:

TITLE:clip_volume[0]: IOP_AUD_DB_CLIP_DA40_ALERT     Name: database_clip_id  VALUE: IOP_AUD_DB_CLIP_DA40_ALERT

TITLE:clip_volume[0]: IOP_AUD_DB_CLIP_DA40_ALERT     Name: attenuation   VALUE: 9

参考附图,为什么

l.td
会跳转到第二个
<tr>
标签。更有趣的是,当我调用
.contents
.children
l
时,第一个
<tr>
及其所有后代都找不到了!请帮忙!

html css python-3.x web-scraping beautifulsoup
1个回答
0
投票

所描述的行为无法用所提供的信息重现;正如评论中已经提到的,这里的问题需要改进。

如果 HTML 以指定的静态形式存在于

soup
中,并且您只想显示每个表格的前两列,包括其前面的
<h3>
文本,则可以从
<div>
开始像这样继续:

for l in soup.div.find_all('tr', class_='odd'):
    ltitle = l.td. text
    value = l.td.next_sibling.text
    print('TITLE:' + l.find_previous('h3').span.next_sibling.text + '\t Name: ' + str(ltitle) + '\t VALUE: ' + str(value))

要获取之前的标题,在本例中仍然引用树:

l.find_previous('h3').span.next_sibling.text

要仅选择第二个表,请调整为:

for l in soup.div.find_all('table')[1].find_all('tr', class_='odd'):
© www.soinside.com 2019 - 2024. All rights reserved.