soup.select()



У библиотеки Beautiful Soup также есть метод soup.select(), который позволяет искать элементы HTML при помощи CSS-селекторов. Возвращается список тегов, соответствующих указанным условиям.

Можно использовать разные CSS-селекторы, например, класс, тег, идентификатор и другие атрибуты. Это позволяет расширить возможности поиска нужного компонента на исходной странице. К примеру, можно использовать селектор p.text-class для нахождения всех тегов <p>, у которых есть класс text-class.

Стоит помнить, что .select() возвращает список найденных тегов, даже если найден один элемент. Если необходимо найти один тег, можно добавить индекс [0] или перейти на использование метода select_one().

Основные отличия .select() от .find()

Метод поиска. .select() использует для поиска CSS-селекторы, .find() ищет элементы при помощи имени тега, атрибута или текста.

Результат. .find() прекращает поиск при нахождении первого подходящего элемента, .select() возвращает список всех элементов, которые соответствуют указанному фильтру.

Гибкость. .select() позволяет получить более широкие возможности при работе со сложными запросами. Облегчается работа с нестандартной структурой или большим количеством вложений.

Общий синтаксис:

soup.select(selector, namespaces=None, limit=None, **kwargs)

Параметры

selector(str) – основной параметр, в который передается строка CSS-селектора. Селекторы могут иметь разную сложность, иметь вложения и так далее. К примеру, конструкция «div.content p» позволяет выбрать все теги <p>, которые расположены внутри блока <div> с классом content.

soup.select("div.content p")

namespaces(dict, optional) – указание пространства имен для тегов XML. Используется, если необходимо обработать документ XML.

Если у вас есть XML с пространствами имен, вы можете использовать namespaces={«ns»: «http://example.com»} и затем использовать CSS-селекторы, например, soup.select(«ns|tag»).

limit=(int, optional) – максимальное количество элементов, которые будут возвращены. Если параметр не указан, будут возвращены все элементы. Пример:

soup.select("p", limit=2)

Примеры использования:

Тег: select(«p»)
Класс: select(«.class»)
Идентификатор: select(«#id»)
Атрибут: select(«[attribute=value]»)
Несколько селекторов: select(«p.class»)
Вложенные элементы: select(«div span»)
Непосредственные дочерние элементы: select(«div > p»)
Элементы с несколькими классами: select(«.class1.class2»)
Элементы с определенными атрибутами: select(«[data-custom]»)
Псевдоклассы CSS: select(«p:first-of-type») или select(«p:last-of-type»)
Соседние элементы: select(«h1 + p»)
Элементы, содержащие определенный текст:

elements = soup.select("p")
elements_with_text = [elem for elem in elements if "определенный текст" in elem.text]
for elem in elements_with_text:
    print(elem.text)

Пример 1

В первом случае выбираются все теги <p>, которые имеют класс text-class,

result = soup.select('p.text-class')

во втором – теги <p> с атрибутом id=»text-id»

​​​​​​​result = soup.select('p#text-id')

а в третьем – все теги <p> внутри тега body. Далее текст из тегов выводится на печать.

result = soup.select('body p')
from bs4 import BeautifulSoup
html = """
<html>
    <body>
        <h1>Заголовок 1</h1>
        <p class="text-class">Текст 1</p>
        <p class="text-class">Текст 2</p>
        <p id="text-id">Текст 3</p>
    </body>
</html>
"""
soup = BeautifulSoup(html, 'html.parser')

# Найти все теги `p` с классом `text-class`
result = soup.select('p.text-class')
for tag in result:
    print(tag.text)
print('----разделитель----')

# Найти все теги `p` с атрибутом id=`text-id`
result = soup.select('p#text-id')
for tag in result:
    print(tag.text)
print('----разделитель----')

# Найти все теги `p` внутри тега `body`
result = soup.select('body p')
for tag in result:
    print(tag.text)

Вывод:

Текст 1
Текст 2
----разделитель----
Текст 3
----разделитель----
Текст 1
Текст 2
Текст 3

Пример 2

Поставлена задача выбрать все теги с классом «highlight»

highlighted_paras = soup.select(".highlight")

Также необходимо выбрать все теги <p>, которые находятся внутри элемента с идентификатором «div1»

div_paras = soup.select("#div1 p")
from bs4 import BeautifulSoup

html = """
<html>
  <body>
    <p class="highlight">This is a highlighted paragraph.</p>
    <p>This is a normal paragraph.</p>
    <div id="div1">
      <p>This is a paragraph in a div.</p>
    </div>
  </body>
</html>
"""
soup = BeautifulSoup(html, "html.parser")

# Выберем все параграфы с классом "highlight"
highlighted_paras = soup.select(".highlight")
for para in highlighted_paras:
    print(para.text)
print('----разделитель----')

# Выберем все параграфы, находящиеся внутри элемента с идентификатором "div1"
div_paras = soup.select("#div1 p")
for para in div_paras:
    print(para.text)

Вывод:

This is a highlighted paragraph.
----разделитель----
This is a paragraph in a div.

Пример 3

Находим теги с классом «highlight», которые при этом находятся внутри элементов с идентификатором «div2» или «div1».

highlighted_paras = soup.select("#div1 .highlight, #div2 .highlight")
from bs4 import BeautifulSoup

html = """
<html>
  <body>
    <div id="div1">
      <p class="highlight">This is a highlighted paragraph in div1.</p>
      <p>This is a normal paragraph in div1.</p>
    </div>
    <div id="div2">
      <p class="highlight">This is a highlighted paragraph in div2.</p>
      <p>This is a normal paragraph in div2.</p>
    </div>
  </body>
</html>
"""
soup = BeautifulSoup(html, "html.parser")

# Выберем все параграфы с классом "highlight", которые
# находятся внутри элементов с идентификатором "div1" или "div2"
highlighted_paras = soup.select("#div1 .highlight, #div2 .highlight")
print("Highlighted paragraphs:")
for para in highlighted_paras:
    print(para.text)

Вывод:

Highlighted paragraphs:
This is a highlighted paragraph in div1.
This is a highlighted paragraph in div2.

Пример 4

Выбираем теги, которые имеют класс «highlight»

highlighted_paras = soup.select("p[class='highlight']")
from bs4 import BeautifulSoup

html = """
<html>
  <body>
    <div id="div1">
      <p class="highlight">This is a highlighted paragraph in div1.</p>
      <p>This is a normal paragraph in div1.</p>
    </div>
    <div id="div2">
      <p class="highlight">This is a highlighted paragraph in div2.</p>
      <p>This is a normal paragraph in div2.</p>
    </div>
  </body>
</html>
"""
soup = BeautifulSoup(html, "html.parser")

# Выберем все параграфы с классом "highlight"
highlighted_paras = soup.select("p[class='highlight']")
print("Highlighted paragraphs:")
for para in highlighted_paras:
    print(para.text)

 Вывод:

Highlighted paragraphs:
This is a highlighted paragraph in div1.
This is a highlighted paragraph in div2.

Может возникнуть ситуация, когда необходимо выбрать все теги, исключив определенные элементы. В этом случае будет полезен псевдокласс :not().

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

# Выберем все параграфы без класса "highlight"
no_highlighted_paras = soup.select("p:not(.highlight)")
print("No_highlighted paragraphs:")
for para in no_highlighted_paras:
    print(para.text)


Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: