selectors.combinators

Module with combinators, which are composite selectors, that define a relationship between multiple selectors related to their position in the document.

Most of them are counterpart of CSS combinators, but others extend their functionality.

Classes

  • ChildCombinator - counterpart of CSS child combinator (>)

  • NextSiblingCombinator - counterpart of CSS adjacent sibling combinator (+)

  • SubsequentSiblingCombinator - counterpart of CSS subsequent sibling combinator (*)

  • DescentCombinator - counterpart of CSS descendant combinator (” “)

  • ParentCombinator - matches parent of preceding selector

  • AncestorCombinator - matches ancestor of preceding selector

Notes

For more information on CSS combinators, see:

https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors/Combinators

class SelectorList(**kwargs)[source]

Bases: SelectorList

class BaseCombinator(selector1: SoupSelector, selector2: SoupSelector, /, *selectors: SoupSelector)[source]

Bases: CompositeSoupSelector

Base class for all combinators, which are composite selectors, that defined a relationship between multiple selectors and apply it to search for elements in the document.

COMMUTATIVE = False
__init__(selector1: SoupSelector, selector2: SoupSelector, /, *selectors: SoupSelector) None[source]

Initializes Combinator object with provided positional arguments. At least two SoupSelector object are required to create Combinator.

Parameters

selectors: SoupSelector

SoupSelector objects to match accepted as positional arguments.

Notes

Object can be initialized with more than two SoupSelector objects, which would be equal to chaining multiple combinators of the same type.

For example, chaining child combinator in css:

Example

>>> div > a > span

translated to soupsavvy would be:

Example

>>> ChildCombinator(TypeSelector("div"), TypeSelector("a"), TypeSelector("span"))

Raises

NotSoupSelectorException

If any of provided parameters is not an instance of SoupSelector.

find_all(tag: IElement, recursive: bool = True, limit: int | None = None) list[IElement][source]

Finds all elements matching selector in provided IElement.

Parameters

tagIElement

Any IElement object to search within.

recursivebool, optional

Specifies if search should be recursive. If set to False, only direct children of the element will be searched. By default True.

limitint, optional

Specifies maximum number of elements to return. By default None, all found elements are returned.

Returns

list[IElement]

List of IElement objects matching selector. If none found, the list is empty.

class BaseAncestorCombinator(selector1: SoupSelector, selector2: SoupSelector, /, *selectors: SoupSelector)[source]

Bases: BaseCombinator

Base class for ancestor combinators, that are specific type of combinators, unlike other combinators, they move up the tree of elements, rather than down after finding first step.

  • Elements that match first step can be found

anywhere in the tree, regardless of recursive parameter. - Final results should contain only children of element if recursive is False.

class ChildCombinator(selector1: SoupSelector, selector2: SoupSelector, /, *selectors: SoupSelector)[source]

Bases: BaseCombinator

Counterpart of CSS child combinator. Represents the relationship between selectors, where every next matching element is a direct child of the previous one.

Example

>>> ChildCombinator(TypeSelector("div"), TypeSelector("a"))

matches all ‘a’ elements that are direct children of ‘div’ elements.

Example

>>> <div class="widget"><a>Hello World</a></div> ✔️
>>> <div class="widget"><span></span><a>Hello World</a></div> ✔️
>>> <span class="widget"><a>Hello World</a></span> ❌
>>> <div class="menu"><span>Hello World</span></div> ❌

Object can be created as well by using greater than operator > on SoupSelector objects.

Example

>>> TypeSelector("div") > TypeSelector("a")

Which is equivalent to the first example.

CSS counterpart can be represented as:

Example

>>> div > a { color: red; }

Notes

For more information on child combinator, see:

https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator

class NextSiblingCombinator(selector1: SoupSelector, selector2: SoupSelector, /, *selectors: SoupSelector)[source]

Bases: BaseCombinator

Counterpart of CSS next sibling combinator. Represents the relationship between selectors, where every next matching element is a sibling immediately following the previous one.

Example

>>> NextSiblingCombinator(TypeSelector("div"), TypeSelector("a"))

matches all ‘a’ elements that immediately follow ‘div’ elements, it means that both elements are children of the same parent element.

Example

>>> <div class="widget"></div><a>Hello World</a> ✔️
>>> <div class="widget"><a>Hello World</a></div> ❌
>>> <div class="widget"></div><span></span><a>Hello World</a> ❌

Object can be created as well by using plus operator + on SoupSelector objects.

Example

>>> TypeSelector("div") + TypeSelector("a")

Which is equivalent to the first example.

CSS counterpart can be represented as:

Example

>>> div + a

Notes

This is also known as the adjacent sibling combinator in CSS. For more information on next sibling combinator, see:

https://developer.mozilla.org/en-US/docs/Web/CSS/Next-sibling_combinator

class SubsequentSiblingCombinator(selector1: SoupSelector, selector2: SoupSelector, /, *selectors: SoupSelector)[source]

Bases: BaseCombinator

Counterpart of CSS subsequent sibling combinator. Represents the relationship between selectors, where every next matching element is a sibling following the previous one, but not necessarily immediately.

Example

>>> SubsequentSiblingCombinator(TypeSelector("div"), TypeSelector("a"))

matches all ‘a’ elements that follow ‘div’ elements.

Example

>>> <div class="widget"></div><a>Hello World</a> ✔️
>>> <div class="widget"><span></span><a>Hello World</a></div> ✔️
>>> <span class="widget"><a>Hello World</a></span> ❌
>>> <a>Hello World</a><div class="menu"></div> ❌

Object can be created as well by using multiplication operator * on SoupSelector objects.

Example

>>> TypeSelector("div") * TypeSelector("a")

CSS counterpart can be represented as:

Example

>>> div ~ a

Notes

This combinator is also known as general sibling combinator in CSS. For more information on subsequent sibling combinator, see:

https://developer.mozilla.org/en-US/docs/Web/CSS/Subsequent-sibling_combinator

class DescendantCombinator(selector1: SoupSelector, selector2: SoupSelector, /, *selectors: SoupSelector)[source]

Bases: BaseCombinator

Counterpart of CSS descendant combinator. Represents the relationship between selectors, where every next matching element is a descendant of the previous one.

Example

>>> DescentCombinator(TypeSelector("div"), ClassSelector("widget"))

matches all descendants of ‘div’ element with ‘widget’ class.

Example

>>> <div><a class="widget"></a></div> ✔️
>>> <div><div><a class="widget"></a></div></div> ✔️
>>> <div><a id="widget"></a></div> ❌
>>> <span><a class="widget"></a></span> ❌
>>> <a class="widget"></a> ❌

Object can be created as well by using right shift operator >> on SoupSelector objects.

Example

>>> TypeSelector("div") >> ClassSelector("widget")

CSS counterpart can be represented as:

Example

>>> div .widget

Notes

For more information on subsequent sibling combinator, see:

https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_combinator

class ParentCombinator(selector1: SoupSelector, selector2: SoupSelector, /, *selectors: SoupSelector)[source]

Bases: BaseAncestorCombinator

Defines a relationship between selectors, where every next matching element is a parent of the previous one.

Example

>>> ParentCombinator(TypeSelector("a"), TypeSelector("div"))

The given selector matches all ‘div’ elements that are parents of ‘a’ elements.

Example

>>> <div><a href="/shop"></a></div> ✔️
>>> <div><span><div><a href="/shop"></a></span></div> ❌
>>> <span><a href="/shop"></a></span> ❌

Object can be created as well by using lt operator < on SoupSelector objects.

Example

>>> TypeSelector("a") < TypeSelector("div")

Although this combinator does not have its counterpart in CSS, it can be represented as:

Example

>>> div:has(> a)
class AncestorCombinator(selector1: SoupSelector, selector2: SoupSelector, /, *selectors: SoupSelector)[source]

Bases: BaseAncestorCombinator

Defines a relationship between selectors, where every next matching element is an ancestor of the previous one.

Example

>>> AncestorCombinator(TypeSelector("a"), TypeSelector("div"))

The given selector matches all ‘div’ elements that are ancestors of ‘a’ elements.

Example

>>> <div><span><a href="/shop"></a></span></div> ✔️
>>> <div><a href="/shop"></a></div> ✔️
>>> <div><span class="menu"></span>/div> ❌
>>> <span><a class="menu"></span>/div> ❌

Object can be created as well by using left shift operator << on SoupSelector objects.

Example

>>> TypeSelector("a") << TypeSelector("div")

Although this combinator does not have its counterpart in CSS, it can be represented as:

Example

>>> div:has(a)