首页 > 解决方案 > 标签为空时使用 Beautifulsoup 填充值

问题描述

我正在尝试解析网页中某个类的所有 td 标签的内容,但即使标签本身没有,我也希望拥有某种占位符内容。例如,html 包含这样的 td 标签:

<td class="odds bdevtt moneylineodds " cfg="">+134</td>
<td class="odds bdevtt moneylineodds " cfg=""></td>
<td class="odds bdevtt moneylineodds " cfg="">-140</td>

我正在尝试获取类似 ['+134', '-', '-140'] 的列表作为输出,因此列表中的条目数等于以 '-' 作为占位符的匹配标签的数量表示标签为空。然而,下面只返回 ['+134','-140']。

soup.find_all('td', attrs={'class': 'odds bdevtt moneylineodds '})

标签: pythonhtmlparsingbeautifulsouptags

解决方案


一种可能的解决方案是使用or运算符:

out = [td.get_text(strip=True) or '-' for td in soup.select('td.odds.bdevtt.moneylineodds')]
print(out)

印刷:

['+134', '-', '-140']

一些快速基准测试:

txt = '''<td class="odds bdevtt moneylineodds " cfg="">+134</td>
<td class="odds bdevtt moneylineodds " cfg=""></td>
<td class="odds bdevtt moneylineodds " cfg="">-140</td>'''
​
from bs4 import BeautifulSoup
from timeit import timeit
​
soup = BeautifulSoup(txt, 'html.parser')
​
def using_or():
    return [td.get_text(strip=True) or '-' for td in soup.select('td.odds.bdevtt.moneylineodds')]
​
def using_if_else_1():
    return [td.text if td.text else '-' for td in soup.select('td.odds.bdevtt.moneylineodds')]
​
def using_if_else_2():
    return [t if (t := td.get_text(strip=True)) else '-' for td in soup.select('td.odds.bdevtt.moneylineodds')]
​
​
t1 = timeit(lambda: using_or(), number=10_000)
t2 = timeit(lambda: using_if_else_1(), number=10_000)
t3 = timeit(lambda: using_if_else_2(), number=10_000)
​
print(t1)
print(t2)
print(t3)
​

这打印:

0.7735823660041206
0.8084569670027122
0.776867889042478

看起来,解决方案在性能方面是 +/- 相同的。


推荐阅读