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)
您正在搜索的文本 Shop
在 span
标记内,因此当您尝试使用正则表达式时,它无法使用正则表达式获取值。
您可以尝试使用正则表达式查找文本,然后查找该文本的父级。
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")'))
我有以下 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)
您正在搜索的文本 Shop
在 span
标记内,因此当您尝试使用正则表达式时,它无法使用正则表达式获取值。
您可以尝试使用正则表达式查找文本,然后查找该文本的父级。
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")'))