Python BeautifulSoup find_all 与正则表达式不匹配文本

Python BeautifulSoup find_all with regex doesn't match text

我有以下 HTML 代码:

<a class="nav-link" href="https://cbd420.ch/fr/tous-les-produits/">
<span class="cbp-tab-title">
                                Shop <i class="fa fa-angle-down cbp-submenu-aindicator"></i></span>
</a>

我想获得具有 Shop 的锚标记作为文本,不考虑前后的间距。我尝试了以下代码,但我一直得到一个空数组:

import re
html  = """<a class="nav-link" href="https://cbd420.ch/fr/tous-les-produits/">
<span class="cbp-tab-title">
                                Shop <i class="fa fa-angle-down cbp-submenu-aindicator"></i></span>
</a>"""
soup = BeautifulSoup(html, 'html.parser')
prog = re.compile('\s*Shop\s*')
print(soup.find_all("a", string=prog))
# Output: []

我还尝试使用 get_text():

检索文本
text = soup.find_all("a")[0].get_text()
print(repr(text))
# Output: '\n\n\t\t\t\t\t\t\t\tShop \n'

和运行下面的代码来确保我的正则表达式是正确的,这似乎是事实。

result = prog.match(text)
print(repr(result.group()))
# Output: '\n\n\t\t\t\t\t\t\t\tShop \n'

我也尝试选择 span 而不是 a,但我遇到了同样的问题。我猜这是 find_all 的问题,我已经阅读了 BeautifulSoup documentation,但我仍然找不到问题所在。任何帮助,将不胜感激。谢谢!

您在这里遇到的问题是,您要查找的文本位于包含子标签的标签中,而当标签包含子标签时,string 属性 为空。

您可以在 .find 调用中使用 lambda 表达式,并且由于您正在寻找固定字符串,因此您可以仅使用 'Shop' in t.text 条件而不是正则表达式检查:

soup.find(lambda t: t.name == "a" and 'Shop' in t.text)

您正在搜索的文本 Shopspan 标记内,因此当您尝试使用正则表达式时,它无法使用正则表达式获取值。

您可以尝试使用正则表达式查找文本,然后查找该文本的父级。

import re
html  = """<a class="nav-link" href="https://cbd420.ch/fr/tous-les-produits/">
<span class="cbp-tab-title">
                                Shop <i class="fa fa-angle-down cbp-submenu-aindicator"></i></span>
</a>"""
soup = BeautifulSoup(html, 'html.parser')
print(soup.find(text=re.compile('Shop')).parent.parent)

如果您有 BS 4.7.1 或更高版本,您可以使用以下 css 选择器。

html  = """<a class="nav-link" href="https://cbd420.ch/fr/tous-les-produits/">
<span class="cbp-tab-title">
                                Shop <i class="fa fa-angle-down cbp-submenu-aindicator"></i></span>
</a>"""
soup = BeautifulSoup(html, 'html.parser')
print(soup.select_one('a:contains("Shop")'))