使用bs4从td colspan标记中提取td文本

2024-05-15 18:07:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目标是从colspan下面的“td”标签中提取所有内容。我刚刚开始学习bs4。到目前为止,我可以从页面中提取所有的“trs”,但是,我只想在名为Disks的info_row类下获取信息。非常感谢您对逻辑和/或代码的任何帮助

这是HTML的摘录

<tbody>
    <tr>
        <td colspan="100%" class="info_row">Disks</td>
    </tr>
    <tr>
        <td> sda </td>
        <td> 123456 </td>
        <td> abcdefg </td>
    </tr>
    <tr>
        <td> sdb </td>
        <td> 123456 </td>
        <td> abcdefg </td>
    </tr>
</tbody>

期望输出:

sda 123456 abcdefg
sbd 123456 abcdefg

到目前为止,我有以下几点:

src = open("my_page.html").read()
soup = BeautifulSoup(src, "html.parser")
tbody = soup.findAll("tbody")
for tr in tbody:
      tds = tr.findAll('td')
      for td in tds:
        print(td.text)

Tags: ininfosrcforhtmltrtdrow
2条回答

此示例仅从表中选择非“colspan”行:

from bs4 import BeautifulSoup


html_doc = """<tbody>
    <tr>
        <td colspan="100%" class="info_row">Disks</td>
    </tr>
    <tr>
        <td> sda </td>
        <td> 123456 </td>
        <td> abcdefg </td>
    </tr>
    <tr>
        <td> sdb </td>
        <td> 123456 </td>
        <td> abcdefg </td>
    </tr>
</tbody>"""

soup = BeautifulSoup(html_doc, "html.parser")

for tr in soup.select("tr:not(:has([colspan]))"):
    print(*[td.get_text(strip=True) for td in tr.select("td")])

印刷品:

sda 123456 abcdefg
sdb 123456 abcdefg

或者:您可以选择包含单元格“磁盘”的行之后的所有行:

for tr in soup.select('tr:has(> td:contains("Disks")) ~ tr'):
    print(*[td.get_text(strip=True) for td in tr.select("td")])

编辑:使用lambda

for tr in soup.find(lambda tag: tag.name == "tr" and tag.text.strip() == "Disks").find_next_siblings("tr"):
    print(*[td.get_text(strip=True) for td in tr.select("td")])

初始for循环会找到tr标记的索引,其中td标记具有class="info_row"和作为Disks的文本,使用该索引,您只需找到下一个tr标记的索引,该标记的文本要提取,并将其用作列表索引,以应用get_text()方法提取标记内的文本:

from bs4 import BeautifulSoup

src = '''<tbody>
    <tr>
        <td colspan="100%" class="info_row">Disks</td>
    </tr>
    <tr>
        <td> sda </td>
        <td> 123456 </td>
        <td> abcdefg </td>
    </tr>
    <tr>
        <td> sdb </td>
        <td> 123456 </td>
        <td> abcdefg </td>
    </tr>
</tbody>'''

soup = BeautifulSoup(src, "html.parser")
trs = soup.findAll("tr")

for i in range(len(trs)):
    if trs[i].td:
        if 'class' in trs[i].td.attrs and trs[i].td.text == 'Disks':
            if "info_row" in trs[i].td.attrs['class']:
                idx = i
                break

print(' '.join(trs[idx+1].get_text(' ').split()))
print(' '.join(trs[idx+2].get_text(' ').split()))

输出

sda 123456 abcdefg
sdb 123456 abcdefg

要获取标记中的单个元素,可以使用此代码,因为trs[idx+1].get_text(' ').split()实际上是一个列表:

for item in trs[idx+1].get_text(' ').split():
    print(item)

for item in trs[idx+2].get_text(' ').split():
    print(item)

输出

sda
123456
abcdefg
sdb
123456
abcdefg

相关问题 更多 >