Прекрасный Суп Объект - PullRequest
0 голосов
/ 03 июля 2018

У меня проблема с красивым супом. В частности, с помощью метода .find. Есть ли способ, которым я могу сделать так, чтобы он соответствовал широкому, а не точному соответствию? Прямо сейчас это работает, только если Первый Последний найден.

soup.find("a", string="First Last").get('href')

Я бы хотел найти любое из этих двух слов с заглавными буквами или без них. так было бы найти

First
first
Last first
last last
something something last
etc..

Спасибо за помощь!

1 Ответ

0 голосов
/ 03 июля 2018

Документация для Виды фильтров подробно объясняет все многие параметры. (Обязательно продолжайте, по крайней мере, разделы find_all(), name и аргументы ключевых слов после этого; именно здесь вы найдете лучшие примеры.)

Тот, который вы используете, делает только точные совпадения:

Самый простой фильтр - это строка. Передайте строку в метод поиска, и Beautiful Soup выполнит сопоставление с этой точной строкой.


Но вместо этого вы можете использовать, например, регулярное выражение :

Если вы передадите объект регулярного выражения, Beautiful Soup выполнит фильтрацию по этому регулярному выражению, используя метод search ().

soup.find("a", string=re.compile(r'(?i)(first|last)'))

… или функция :

Если ни одно из других соответствий не работает для вас, определите функцию, которая принимает элемент в качестве единственного аргумента. Функция должна вернуть True, если аргумент совпадает, и False в противном случае.

def matches_firstlast(s):
    lower = s.casefold()
    return 'first' in lower or 'last' in lower
soup.find("a", string=matches_firstlast)

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


Вы не очень четко указали, какое именно правило вы хотите, или дали нам полный пример для проверки, поэтому я не могу обещать, что регулярное выражение или функция действительно будут выполнять то, что вы хотите. Вот пример:

>>> h =  '<a>first</a> <a>last first</a> <a>something something last</a> <a>larst fist</a> <p>First Last</p>'
>>> soup = BeautifulSoup(h, 'lxml')
>>> soup.find_all("a", string=re.compile(r'(?i)(first|last)'))
[<a>first</a>, <a>last first</a>, <a>something something last</a>]
>>> soup.find_all("a", string=matches_firstlast)
[<a>first</a>, <a>last first</a>, <a>something something last</a>]

Надеюсь, этого и документации достаточно, чтобы закодировать все, что вам нужно.

...