Python BeautifulSoup find_all с регулярным выражением не соответствует тексту - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть следующий 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'

и запустил следующий код для убедитесь, что мой Regex был прав, что похоже на случай.

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 , но я все еще не могу найти проблему. Любая помощь будет оценена. Спасибо!

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Проблема, с которой вы столкнулись, заключается в том, что искомый текст находится в теге, который содержит дочерние теги, а когда тег имеет дочерние теги, свойство string пусто.

Вы можете использовать лямбда-выражение в вызове .find и, поскольку вы ищете фиксированную строку, вы можете использовать простое условие 'Shop' in t.text вместо проверки регулярного выражения:

soup.find(lambda t: t.name == "a" and 'Shop' in t.text)
0 голосов
/ 30 апреля 2020

Текст 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")'))
...