В модуле BeautifulSoup4 есть метод BeautifulSoup.select()
, который использует SoupSieve
, чтобы запустить CSS селектор и вернуть все подходящие элементы. В объекте Tag
есть похожий метод, который запускает CSS селектор в отношении содержимого одного тега.
Интеграция SoupSieve
была добавлена в BeautifulSoup4.7.0. В более ранних версиях также есть метод .select()
, но он поддерживат только самые часто используемые селекторы CSS. Если BeautifulSoup4 устанавливался через pip
, то одновременно должен был установиться SoupSieve
.
:link
.:checked
.:default
.:disabled
.:empty
.:enabled
.:first-child
.:first-of-type
.:has()
.:in-range
.:indeterminate
.:is()
.:last-child
.:last-of-type
.:not()
.:nth-child()
.:nth-last-child()
.:nth-last-of-type()
.:nth-of-type()
.:only-child
.:only-of-type
.:optional
.:out-of-range
.:placeholder-shown
.:read-only
.:read-write
.:required
.:scope
.:where()
.Синтаксис:
element
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div>Here is some text.</div> <div>Here is some more text.</div> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('div') # [<div>Here is some text.</div>, # <div>Here is some more text.</div>]
Синтаксис:
#id
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div id="some-id">Here is some text.</div> <div>Here is some more text.</div> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('#some-id') # [<div id="some-id">Here is some text.</div>]
Синтаксис:
.class
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div class="some-class">Here is some text.</div> <div>Here is some more text.</div> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('.some-class') # [<div class="some-class">Here is some text.</div>]
[attribute]
:Ищет HTML-элементы с атрибутом attribute
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <ul> <li><a href="#internal">Internal link</a></li> <li><a href="http://example.com">Example link</a></li> <li><a href="#InSensitive">Insensitive internal link</a></li> <li><a href="http://example.org">Example org link</a></li> </ul> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('[href]') # [<a href="#internal">Internal link</a>, # <a href="http://example.com">Example link</a>, # <a href="#InSensitive">Insensitive internal link</a>, # <a href="http://example.org">Example org link</a>]
[attribute="value"]
:Ищет HTML-элементы с атрибутом attribute
, который имеет значение value
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <ul> <li><a href="#internal">Internal link</a></li> <li><a href="http://example.com">Example link</a></li> <li><a href="#InSensitive">Insensitive internal link</a></li> <li><a href="http://example.org">Example org link</a></li> </ul> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('[href="#internal"]') # [<a href="#internal">Internal link</a>]
[attribute~="value"]
:Ищет HTML-элементы с атрибутом attribute
, где значение value
встречается в строке, представляющей список разделенный пробелом.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <ul> <li><a href="#internal" class="class1 class2 class3">Internal link</a></li> <li><a href="http://example.com">Example link</a></li> <li><a href="#InSensitive">Insensitive internal link</a></li> <li><a href="http://example.org">Example org link</a></li> </ul> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('[class~=class2]') # [<a class="class1 class2 class3" href="#internal">Internal link</a>]
[attribute|="value"]
:Ищет HTML-элементы с атрибутом attribute
, значение которого представляет собой список разделенный черточками, и который начинается со значения value
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div lang="en">Some text</div> <div lang="en-US">Some more text</div> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('div[lang|="en"]') # [<div lang="en">Some text</div>, # <div lang="en-US">Some more text</div>]
[attribute^="value"]
:Ищет HTML-элементы с атрибутом attribute
, значение которого начинается с value
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <ul> <li><a href="#internal">Internal link</a></li> <li><a href="http://example.com">Example link</a></li> <li><a href="#InSensitive">Insensitive internal link</a></li> <li><a href="http://example.org">Example org link</a></li> </ul> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('[href^=http]') # [<a href="http://example.com">Example link</a>, # <a href="http://example.org">Example org link</a>]
[attribute$="value"]
:Ищет HTML-элементы с атрибутом attribute
, значение которого заканчивается на value
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <ul> <li><a href="#internal">Internal link</a></li> <li><a href="http://example.com">Example link</a></li> <li><a href="#InSensitive">Insensitive internal link</a></li> <li><a href="http://example.org">Example org link</a></li> </ul> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('[href$=org]') # [<a href="http://example.org">Example org link</a>]
[attribute*="value"]
:Ищет HTML-элементы с атрибутом attribute
, значение которого содержит подстроку value
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <html> <head></head> <body> <ul> <li><a href="#internal">Internal link</a></li> <li><a href="http://example.com">Example link</a></li> <li><a href="#InSensitive">Insensitive internal link</a></li> <li><a href="http://example.org">Example org link</a></li> </ul> </body> </html> """ >>> soup = bs(html, 'html.parser') >>> soup.select('[href*="example"]') # [<a href="http://example.com">Example link</a>, # <a href="http://example.org">Example org link</a>]
[attribute!="value"]
:Ищет HTML-элементы с атрибутом attribute
, значение которого НЕ равно value
(эквивалентно :not([attribute=value])
).
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <ul> <li><a href="#internal">Internal link</a></li> <li><a href="http://example.com">Example link</a></li> <li><a href="#InSensitive">Insensitive internal link</a></li> <li><a href="http://example.org">Example org link</a></li> </ul> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('a[href!="#internal"]') # или >>> soup.select('a:not([href="#internal"])') # [<a href="http://example.com">Example link</a>, # <a href="#InSensitive">Insensitive internal link</a>, # <a href="http://example.org">Example org link</a>]
[attribute="value" s]
:Ищет HTML-элементы с атрибутом attribute
, значение которого совпадает с value
с учетом регистра.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <ul> <li><a href="#internal">Internal link</a></li> <li><a href="http://example.com">Example link</a></li> <li><a href="#InSensitive">Insensitive internal link</a></li> <li><a href="http://example.org">Example org link</a></li> </ul> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('[href="#INTERNAL" s]') # [] >>> soup.select('[href="#internal" s]') # [<a href="#internal">Internal link</a>]
Для объединения нескольких селекторов в списке, необходимо использовать запятую, например 'h1, p'
. При представлении списка селекторов любой селектор в списке, соответствующий HTML-тегу, вернет этот элемент.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <h1>Title</h1> <p>Paragraph</p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('h1, p') # [<h1>Title</h1>, <p>Paragraph</p>]
Комбинаторы потомков объединяют два селектора пробелами, например 'body p'
. Это означает, что второй элемент будет найден только в том случае, если у него есть предок, соответствующий первому элементу.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div><p>Paragraph 1</p></div> <div><p>Paragraph 2</p></div> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('body p') # [<p>Paragraph 1</p>, <p>Paragraph 2</p>]
Комбинатор дочерних элементов объединяют два селектора знаком >
, например 'div > p'
. Это означает, что второй элемент будет найден только в том случае, если у него есть родитель, соответствующий первому элементу.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div><p>Paragraph 1</p></div> <div><ul><li><p>Paragraph 2</p></li></ul></div> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('div > p') # [<p>Paragraph 1</p>]
Комбинаторы одноуровневых соседей объединяют два селектора знаком ~
, например 'h1 ~ p'
. Это означает, что второй элемент будет найден только в том случае, если у него есть одноуровневый сосед, который предшествует ему, и соответствует первому элементу.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('h1 ~ p') # [<p>Paragraph 1</p>, <p>Paragraph 2</p>]
Комбинатор соседнего элемента объединяет два селектора знаком +
, например 'h1 + p'
. Это означает, что второй элемент будет найден только в том случае, если перед ним непосредственно находится сосед, который соответствует первому элементу.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('h1 + p') # [<p>Paragraph 1</p>]
Здесь представлены псевдоклассы, которые поддерживаются полностью или частично. Частичная поддержка обычно связана с ограничениями, связанными с отсутствием активной среды браузера.
Любые селекторы, которые не указаны здесь относятся к категории неприменимых.
:link
:Выбирает каждый элемент <a>
или <area>
, имеющий атрибут href
, независимо от того, посещался ли он.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p>A link to <a href="http://example.com">click</a></p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select(':link') # [<a href="http://example.com">click</a>]
:checked
:Выбирает любой элемент <input type="radio"/>
, <input type="checkbox"/>
или <option>
(в элементе <select>
), который отмечен или переключен в состояние включено.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div> <input type="radio" name="my-input" id="yes" checked> <label for="yes">Yes</label> <input type="radio" name="my-input" id="no"> <label for="no">No</label> </div> <select name="my-select" id="fruit"> <option id="1" value="opt1">Apples</option> <option id="2" value="opt2" selected>Grapes</option> <option id="3" value="opt3">Pears</option> </select> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select(':checked') # [<input checked="" id="yes" name="my-input" type="radio"/>, # <option id="2" selected="" value="opt2">Grapes</option>]
:default
:Выбирает любой элемент формы, который является элементом по умолчанию среди группы связанных элементов, в том числе: <button>
, <input type="radio"/>
, <input type="checkbox"/>
и <option>
(в элементе <select>
) .
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <form> <input type="radio" name="season" id="spring"> <label for="spring">Spring</label> <input type="radio" name="season" id="summer" checked> <label for="summer">Summer</label> <input type="radio" name="season" id="fall"> <label for="fall">Fall</label> <input type="radio" name="season" id="winter"> <label for="winter">Winter</label> <select id="pet-select"> <option value="">--Please choose an option--</option> <option id="dog" value="dog">Dog</option> <option id="cat" value="cat">Cat</option> <option id="hamster" value="hamster" selected>Hamster</option> <option id="parrot" value="parrot">Parrot</option> <option id="spider" value="spider">Spider</option> <option id="goldfish" value="goldfish">Goldfish</option> </select> </form> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select(':default') # [<input checked="" id="summer" name="season" type="radio"/>, # <option id="hamster" selected="" value="hamster">Hamster</option>]
:disabled
:Выбирает любой отключенный элемент.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <form action="#"> <fieldset id="shipping"> <legend>Shipping address</legend> <input type="text" placeholder="Name"> <input type="text" placeholder="Address"> <input type="text" placeholder="Zip Code"> </fieldset> <br> <fieldset id="billing"> <legend>Billing address</legend> <label for="billing-checkbox">Same as shipping address:</label> <input type="checkbox" id="billing-checkbox" checked> <br> <input type="text" placeholder="Name" disabled> <input type="text" placeholder="Address" disabled> <input type="text" placeholder="Zip Code" disabled> </fieldset> </form> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('input:disabled') # [<input disabled="" placeholder="Name" type="text"/>, # <input disabled="" placeholder="Address" type="text"/>, # <input disabled="" placeholder="Zip Code" type="text"/>]
:empty
:Выбирает элементы, у которых нет дочерних элементов и текста (пробелы игнорируются).
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <span> <!-- comment --> </span> <span></span> <span><span> </span></span> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('body:empty') # [<span> <!-- comment --> </span>, # <span></span>, # <span> </span>]
:enabled
:Выбирает любой активный/включенный элемент.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <form action="#"> <fieldset id="shipping"> <legend>Shipping address</legend> <input type="text" placeholder="Name"> <input type="text" placeholder="Address"> <input type="text" placeholder="Zip Code"> </fieldset> <br> <fieldset id="billing"> <legend>Billing address</legend> <label for="billing-checkbox">Same as shipping address:</label> <input type="checkbox" id="billing-checkbox" checked> <br> <input type="text" placeholder="Name" disabled> <input type="text" placeholder="Address" disabled> <input type="text" placeholder="Zip Code" disabled> </fieldset> </form> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('input:enabled') # [<input placeholder="Name" type="text"/>, # <input placeholder="Address" type="text"/>, # <input placeholder="Zip Code" type="text"/>, # <input checked="" id="billing-checkbox" type="checkbox"/>]
:first-child
:Выбирает первый элемент в группе одноуровневых элементов.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <p id="2"></p> <p id="3"></p> <p id="4"></p> <p id="5"></p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('p:first-child') # [<p id="0"></p>]
:first-of-type
:Выбирает первый элемент данного типа в группе родственных элементов.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <span id="2"></span> <span id="3"></span> <span id="4"></span> <span id="5"></span> <span id="6"></span> <p id="7"></p> <p id="8"></p> <p id="9"></p> <p id="10"></p> <span id="11"></span> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('span:first-of-type') # [<span id="2"></span>]
:has()
:Выбирает элемент, если какой-либо из относительных селекторов, переданных в качестве параметров (которые относятся к :scope
данного элемента), соответствует хотя бы одному элементу.
Спецификации CSS4 говорится, что :has()
поддерживают составные селекторы, а сложные селекторы запланированы для селекторов CSS5. BeautifulSoup4 поддерживает сложные селекторы.
Синтаксис:
:has(selector)
;:has(> selector)
;:has(~ selector)
;:has(+ selector)
;:has(selector1, > selector2, ~ selector3, + selector4)
;>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div><p>Test <span>paragraph</span></p></div> <div><p class="class">Another test paragraph</p></div> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('div:has(span, > .class)') # [<div><p>Test <span>paragraph</span></p></div>, # <div><p class="class">Another test paragraph</p></div>]
:in-range
:Выбирает все <input>
, значения которых находятся в диапазоне в соответствии с их атрибутами type
, min
, и max
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <input id="0" type="month" min="1980-02" max="2004-08" value="1999-05"> <input id="7" type="month" min="1980-02" max="2004-08" value="1979-02"> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select(':in-range') # [<input id="0" max="2004-08" min="1980-02" type="month" value="1999-05"/>]
:indeterminate
:Выбирает все элементы формы, которые находятся в неопределенном состоянии.
Элемент считается неопределенным, если:
<input type="checkbox"/>
установлен атрибут indeterminate
.<input type="radio"/>
с одинаковым значением атрибута name
не имеет выбранного значения checked
.<progress>
без значения.>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <input type="checkbox" id="checkbox1" indeterminate> <label for="checkbox1">I like cats.</label> <input type="checkbox" id="checkbox2"> <label for="checkbox2">I like dogs.</label> <form> <input type="radio" name="test" id="radio1"> <label for="radio1">Yes</label> <input type="radio" name="test" id="radio2"> <label for="radio2">No</label> <input type="radio" name="test" id="radio3"> <label for="radio3">Maybe</label> </form> <form> <input type="radio" name="another" id="radio4"> <label for="radio4">Red</label> <input type="radio" name="another" id="radio5" checked> <label for="radio5">Green</label> <input type="radio" name="another" id="radio6"> <label for="radio6">Blue</label> </form> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select(':indeterminate') # [<input id="checkbox1" indeterminate="" type="checkbox"/>, # <input id="radio1" name="test" type="radio"/>, # <input id="radio2" name="test" type="radio"/>, # <input id="radio3" name="test" type="radio"/>]
:is()
:Выбирает элемент, но только если он соответствует хотя бы одному селектору в списке селекторов.
Также поддерживается псевдоним :matches()
, т.к. это было исходное имя селектора, и некоторые браузеры до сих пор его поддерживают. Настоятельно рекомендуется использовать :is()
, поскольку поддержка :matches()
может быть удалена в будущем.
Хотя в спецификациях CSS4 указано, что поддерживаются составные селекторы, некоторые браузеры (например Safari) поддерживают сложные селекторы, которые запланированы для селекторов CSS5. BeautifulSoup4 также поддерживает сложные селекторы.
Синтаксис:
:is(selector1, selector2)
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0">Some text <span id="1"> in a paragraph</span>. <a id="2" href="http://google.com">Link.</a></p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('[id]:is(a, span)') # [<span id="1"> in a paragraph</span>, # <a href="http://google.com" id="2">Link.</a>]
:last-child
:Выбирает последний элемент из группы родственных элементов.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <p id="2"></p> <p id="3"></p> <p id="4"></p> <p id="5"></p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('p:last-child') # [<p id="5"></p>]
:last-of-type
:Выбирает последний элемент данного типа в группе родственных элементов. Если перевести "last of type", то получится последний в своем роде.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <span id="2"></span> <span id="3"></span> <span id="4"></span> <span id="5"></span> <span id="6"></span> <p id="7"></p> <p id="8"></p> <p id="9"></p> <p id="10"></p> <span id="11"></span> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('span:last-of-type') # [<span id="11"></span>]
:not()
:Выбирает все элементы, которые не соответствуют селектору. Спецификация CSS3 гласит, что :not()
поддерживает только простые селекторы.
Синтаксис CSS 3:
:not(simple-selector)
.>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div>Here is some text.</div> <div>Here is some more text.</div> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('div:not(:-soup-contains(more))') [<div>Here is some text.</div>]
Выбирает все элементы, которые не соответствуют ни одному из селекторов в списке селекторов. Хотя в спецификациях CSS4 указано, что поддерживаются составные селекторы, некоторые браузеры (Safari) поддерживают сложные селекторы, которые запланированы для селекторов CSS5. Soup Sieve также поддерживает сложные селекторы.
Синтаксис CSS 4:
:not(compound.selector, complex > selector)
.>>> from bs4 import BeautifulSoup as bs >>> html = """ <html> <head></head> <body> <div>Here is some text.</div> <div>Here is some more text.</div> </body> </html> """ >>> soup = bs(html, 'html.parser') >>> soup.select('*:not(html, head, body)')) # [<div>Here is some text.</div>, # <div>Here is some more text.</div>]
:nth-child()
:Сопоставляет элементы в зависимости от их положения в группе братьев и сестер.
Ключевые слова even
и odd
соответственно будут выбирать элементы, положение которых является четным или нечетным среди одноуровневой группы.
Шаблоны в форме an+b
выбирают элементы на основе их положения в одноуровневой группе для каждого положительного целого числа или нулевого значения n
. Индекс первого элемента равен 1
. Значения a
и b
должны быть целыми числами.
Синтаксис:
:nth-child(even)
;:nth-child(odd)
;:nth-child(2)
;:nth-child(2n+2)
.>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <p id="2"></p> <p id="3"></p> <p id="4"></p> <p id="5"></p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('p:nth-child(even)') # [<p id="1"></p>, <p id="3"></p>, <p id="5"></p>] >>> soup.select('p:nth-child(odd)') # [<p id="0"></p>, <p id="2"></p>, <p id="4"></p>] >>> soup.select('p:nth-child(2)') # [<p id="1"></p>] >>> soup.select('p:nth-child(-n+3)') # [<p id="0"></p>, <p id="1"></p>, <p id="2"></p>]
CSS 4 добавляет дополнительный шаблон в форме an+b of S
, где S
представляет собой список селекторов. Шаблон an+b
также можно заменить на even
или odd
.
При использовании шаблона an+b of S
, он будет выбирать элементы из подгруппы одноуровневых элементов, которые все соответствуют списку селектора ([of S]?)
, в зависимости от их положения в этой подгруппе, используя шаблон an+b
для каждого положительного целого или нулевого значения n
. Индекс первого элемента равен 1
. Значения a
и b
должны быть целыми числами.
По сути, img:nth-of-type(2)
будет эквивалентен :nth-child(2 of img)
. Преимущество использования :nth-child(an+b [of S]?)
Перед :nth-of-type
заключается в том, что :nth-of-type
ограничивается типами, а :nth-child(an+b [of S ]?)
могут использовать сложные селекторы.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <p id="2"></p> <p id="3"></p> <p id="4"></p> <p id="5"></p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('*:nth-child(-n+3 of [id])') # [<p id="0"></p>, <p id="1"></p>, <p id="2"></p>]
:nth-last-child()
:Сопоставляет элементы в зависимости от их положения в одноуровневой группе, считая с конца.
Считая с конца, ключевые слова even
и odd
будут соответственно выбирать элементы, положение которых является четным или нечетным среди одноуровневой группы.
Считая с конца, шаблоны в форме an+b выбирают элементы на основе их положения в одноуровневой группе для каждого положительного целого или нулевого значения
n. Индекс первого элемента равен
1. Значения
aи
b` должны быть целыми числами.
Синтаксис:
:nth-last-child(even)
;:nth-last-child(odd)
;:nth-last-child(2)
;:nth-last-child(2n+2)
.>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <p id="2"></p> <p id="3"></p> <p id="4"></p> <p id="5"></p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('p:nth-last-child(even)') # [<p id="0"></p>, <p id="2"></p>, <p id="4"></p>] >>> soup.select('p:nth-last-child(odd)') # [<p id="1"></p>, <p id="3"></p>, <p id="5"></p>] >>> soup.select('p:nth-last-child(2)') # [<p id="4"></p>] >>> soup.select('p:nth-last-child(-n+3)') # [<p id="3"></p>, <p id="4"></p>, <p id="5"></p>]
CSS 4 добавляет дополнительный шаблон в форме an+b of S
, где S
представляет собой список селекторов. шаблон an+b
также можно заменить на even
или odd
.
Более подробно о поведении шаблона an+b of S
смотрите описание в описание псевдокласса :nth-child()
для CSS 4
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <p id="2"></p> <p id="3"></p> <p id="4"></p> <p id="5"></p> </html> """ >>> soup = bs(html, 'html.parser') >>> soup.select('*:nth-last-child(-n+3 of [id])') # [<p id="3"></p>, <p id="4"></p>, <p id="5"></p>]
:nth-last-of-type()
:Сопоставляет элементы данного типа в зависимости от их положения в одноуровневой группе, считая с конца.
Ключевые слова even
и odd
будут соответственно выбирать элементы из подгруппы одноуровневых элементов, которые все соответствуют заданному типу, чья позиция является четной или нечетной. Исходное положение отсчитывается с конца.
Шаблоны в форме an+b выбирают из подгруппы одноуровневых элементов, которые все соответствуют заданному типу, в зависимости от их положения для каждого положительного целого или нулевого значения
n. Индекс первого элемента равен 1. Значения
aи
b` должны быть целыми числами. Исходное положение отсчитывается с конца.
Синтаксис:
element:nth-last-of-type(even)
;element:nth-last-of-type(odd)
;element:nth-last-of-type(2)
;element:nth-last-of-type(2n+2)
.>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <span id="2"></span> <span id="3"></span> <span id="4"></span> <span id="5"></span> <span id="6"></span> <p id="7"></p> <p id="8"></p> <p id="9"></p> <p id="10"></p> <span id="11"></span> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('span:nth-last-of-type(even)') # [<span id="2"></span>, <span id="4"></span>, <span id="6"></span>] >>> soup.select('span:nth-last-of-type(odd)') # [<span id="3"></span>, <span id="5"></span>, <span id="11"></span>] >>> soup.select('p:nth-last-of-type(2)') # [<p id="9"></p>] >>> soup.select('p:nth-last-of-type(-n+3)') # [<p id="8"></p>, <p id="9"></p>, <p id="10"></p>]
:nth-of-type()
:Сопоставляет элементы данного типа в зависимости от их положения в группе одноуровневых элементов.
Ключевые слова even
и odd
будут соответственно выбирать элементы из подгруппы одноуровневых элементов, которые все соответствуют заданному типу, чья позиция является четной или нечетной.
Шаблоны в форме an+b выбирают из подгруппы одноуровневых элементов, которые все соответствуют заданному типу, в зависимости от их положения для каждого положительного целого или нулевого значения
n. Индекс первого элемента равен 1. Значения
aи
b` должны быть целыми числами.
Синтаксис:
element:nth-of-type(even)
;element:nth-of-type(odd)
;element:nth-of-type(2)
;element:nth-of-type(2n+2)
.>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <span id="2"></span> <span id="3"></span> <span id="4"></span> <span id="5"></span> <span id="6"></span> <p id="7"></p> <p id="8"></p> <p id="9"></p> <p id="10"></p> <span id="11"></span> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('span:nth-of-type(even)') # [<span id="3"></span>, <span id="5"></span>, <span id="11"></span>] >>> soup.select('span:nth-of-type(odd)') # [<span id="2"></span>, <span id="4"></span>, <span id="6"></span>] >>> soup.select('p:nth-of-type(2)') # [<p id="1"></p>] >>> soup.select('p:nth-of-type(-n+3)') # [<p id="0"></p>, <p id="1"></p>, <p id="7"></p>]
:only-child
:Выбирает элемент, который не имеет одноуровневых элементов, т.е. он является единственным дочерним элементом.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div> <p id="0"></p> <p id="1"></p> <p id="2"></p> <p id="3"></p> <p id="4"></p> <p id="5"></p> </div> <div> <p id="6"></p> </div> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('p:only-child') # [<p id="6"></p>]
:only-of-type
:Выбирает элемент соответствующий данному типу, который не имеет одноуровневых элементов, т.е. он является единственным дочерним элементом.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0"></p> <p id="1"></p> <span id="2"></span> <p id="3"></p> <p id="4"></p> <p id="5"></p> <p id="6"></p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('span:only-of-type') # [<span id="2"></span>]
:optional
:Выбирает любой элемент <input>
, <select>
или <textarea>
, для которого не задан атрибут required
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <form> <input type="name" required> <input type="checkbox" required> <input type="email"> <textarea name="name" cols="30" rows="10" required></textarea> <select name="nm" required> <!-- options --> </select> </form> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select(':optional') # [<input type="email"/>]
:out-of-range
:Выбирает все элементы <input>
, значения которых выходят за пределы диапазона, в соответствии с их атрибутами type
, min
и max
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <input id="0" type="month" min="1980-02" max="2004-08" value="1999-05"> <input id="7" type="month" min="1980-02" max="2004-08" value="1979-02"> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select(':out-of-range') # [<input id="7" max="2004-08" min="1980-02" type="month" value="1979-02"/>]
:placeholder-shown
:Выбирает элемент <input>
или <textarea>
, который в данный момент отображает текст - заполнитель с помощью атрибута placeholder
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <input id="0" placeholder="This is some text"> <textarea id="1" placeholder="This is some text"></textarea> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select(':placeholder-shown') # [<input id="0" placeholder="This is some text"/>, # <textarea id="1" placeholder="This is some text"></textarea>]
:read-only
:Выбирает элементы (<input>
или <textarea>
), которые пользователь не может редактировать. Это относится не только к элементам формы, но и к любому элементу, который может редактироваться пользователем, например к элементу <p>
с установленным на нем contenteditable
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <input id="0"> <input id="1" disabled> <input id="2" type="number" readonly> <textarea id="3"></textarea> <p id="4">Not editable</p> <p id="5" contenteditable="true">Editable text</p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('body :read-only') # [<input disabled="" id="1"/>, # <input id="2" readonly="" type="number"/>, # <p id="4">Not editable</p>]
:read-write
:Выбирает элементы (<input>
или <textarea>
), доступные для редактирования пользователем. Это относится не только к элементам формы, но и к любому элементу, который может быть отредактирован пользователем, например, к элементу <p>
с установленным на нем значением contenteditable
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <input id="0"> <input id="1" disabled> <input id="2" type="number" readonly> <textarea id="3"></textarea> <p id="4">Not editable</p> <p id="5" contenteditable="true">Editable text</p> </html> """ >>> soup = bs(html, 'html.parser') >>> soup.select('body :read-write') # [<input id="0"/>, # <textarea id="3"></textarea>, # <p contenteditable="true" id="5">Editable text</p>]
:required
:Выбирает любой элемент <input>
, <select>
или <textarea>
, для которого установлен атрибут required
.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <form> <input type="name" required> <input type="checkbox" required> <input type="email"> <textarea name="name" cols="30" rows="10" required></textarea> <select name="nm" required> <!-- options --> </select> </form> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select(':required') # [<input required="" type="name"/>, # <input required="" type="checkbox"/>, # <textarea cols="30" name="name" required="" rows="10"></textarea>, # <select name="nm" required=""> # <!-- options --> # </select>]
:scope
:Псевдокласс :scope
представляет элемент, для которого вызывается match
, select
, или filter
. Например, если вызвать объект BeautifulSoup
, представляющий весь документ, то псевдокласс :scope
просто выберет весь HTML-документ.
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <div>Here is some text.</div> <div>Here is some more text.</div> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select_one('body').select(':scope > div') # [<div>Here is some text.</div>, <div>Here is some more text.</div>]
:where()
:Выбирает элемент, но только если он соответствует хотя бы одному селектору в списке селекторов. BeautifulSoup4 не заботится о специфичности, поэтому :where()
по сути является просто псевдонимом для :is()
.
Синтаксис:
:where(selector1, selector2)
>>> from bs4 import BeautifulSoup as bs >>> html = """ <body> <p id="0">Some text <span id="1"> in a paragraph</span>. <a id="2" href="http://google.com">Link.</a></p> </body> """ >>> soup = bs(html, 'html.parser') >>> soup.select('[id]:where(a, span)') # [<span id="1"> in a paragraph</span>, # <a href="http://google.com" id="2">Link.</a>]