selectors.relative
Module with relative selectors and utility components. They are used for selecting elements based on their relation to the anchor element.
Classes
RelativeChild - matches direct children of the anchor element
RelativeDescendant - matches descendants of the anchor element
RelativeNextSibling - matches next sibling of the anchor element
RelativeSubsequentSibling - matches subsequent siblings of the anchor element
RelativeParent - matches parent of the anchor element
RelativeAncestor - matches ancestors of the anchor element
HasSelector - selects elements based on matching reference elements
Anchor - Anchor object for easily creating relative selectors
- class RelativeSelector(selector: SoupSelector)[source]
Bases:
SoupSelectorBase class for relative selectors, that are used to find elements relative to the element that is being searched, which is considered an anchor.
CSS definition of relative selectors state, that it is a selector representing an element relative to one or more anchor elements preceded by a combinator.
In this use case, the anchor element is the element that is being searched, and the combinator is the logic of specific relative selector that is used.
Example
>>> selector = Anchor > TypeSelector("div") ... selector.find_all(tag)
Uses RelativeChild selector to find any div tag that is a direct child of the tag that is being searched (passed as an argument).
In css such selectors can be used for example in :has pseudo-class, where selector is anchored to the element:
Example
>>> :has(> div)
Selects any element that has a direct child div tag.
Notes
Recursive parameter is ignored in relative selectors, as they have their own logic of searching the document.
- __init__(selector: SoupSelector) None[source]
Initializes RelativeSelector instance with specified selector.
Parameters
- selectorSoupSelector
Selector that is used to find tags relative to the anchor element.
- property selector: SoupSelector
Returns selector used to find elements relative to the anchor element in this relative selector.
Returns
- SoupSelector
Selector used for searching elements relative to the anchor element.
- class BaseRelativeSibling(selector: SoupSelector)[source]
Bases:
RelativeSelectorBase class with implementation for relative sibling selectors, searches for next sibling(s) of the anchor element. Child class needs to define: - ‘_limit’ - class attribute to specify how many next siblings to search for. - ‘_func’ - class attribute to specify which method to use for finding siblings.
- 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 BaseAncestorSelector(selector: SoupSelector)[source]
Bases:
RelativeSelectorBase class with implementation for ancestor selectors, searches for ancestor(s) of the anchor element. Child class needs to define: - ‘_limit’ - class attribute to specify how many ancestors to search for.
- 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 RelativeChild(selector: SoupSelector)[source]
Bases:
RelativeSelectorSelector for finding direct children of the anchor element.
Example
>>> RelativeChild(TypeSelector("p"))
when ‘div’ element is passed into find methods:
Example
>>> <div><p></p></div> ✔️ >>> <div><a><p></p></a></div> ❌ >>> <div><a></a></div> ❌
It can be created with Anchor instance as well with use of gt operator >:
Example
>>> Anchor > TypeSelector("p")
Notes
Behavior of RelativeChild selector is equivalent to using find methods of selector with recursive=False and is implemented to support ‘HasSelector’ and ChildCombinator selectors.
- 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 RelativeDescendant(selector: SoupSelector)[source]
Bases:
RelativeSelectorSelector for finding descendants of the anchor element.
Example
>>> RelativeDescendant(TypeSelector("p"))
when ‘div’ element is passed into find methods:
Example
>>> <div><p></p></div> ✔️ >>> <div><a><p></p></a></div> ✔️ >>> <div><a></a></div> ❌ >>> <div></div><p></p> ❌
It can be created with Anchor instance as well with use of right shift operator >>:
Example
>>> Anchor >> TypeSelector("p")
Notes
Behavior of RelativeDescendant selector is equivalent to using find methods of selector with default recursive=True and is implemented to support ‘HasSelector’ and DescendantCombinator selectors.
- 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 RelativeNextSibling(selector: SoupSelector)[source]
Bases:
BaseRelativeSiblingSelector for finding next sibling of the anchor element.
Example
>>> RelativeNextSibling(TypeSelector("p"))
when ‘div’ element is passed into find methods:
Example
>>> <div></div><p></p> ✔️ >>> <div></div><a></a><p></p> ❌ >>> <p></p><div></div> ❌
It can be created with Anchor instance as well with use of plus operator +:
Example
>>> Anchor + TypeSelector("p")
- class RelativeSubsequentSibling(selector: SoupSelector)[source]
Bases:
BaseRelativeSiblingSelector for finding subsequent siblings of the anchor element.
Example
>>> RelativeSubsequentSibling(TypeSelector("p"))
when ‘div’ element is passed into find methods:
Example
>>> <div></div><p></p> ✔️ >>> <div></div><a></a><p></p> ✔️ >>> <p></p><div></div> ❌ >>> <div></div><span><p></p></span> ❌
It can be created with Anchor instance as well with use of multiplication operator *:
Example
>>> Anchor * TypeSelector("p")
- class RelativeParent(selector: SoupSelector)[source]
Bases:
BaseAncestorSelectorSelector for finding parent of the anchor element.
Example
>>> RelativeParent(TypeSelector("div"))
when ‘p’ element is passed into find methods:
Example
>>> <div><p></p></div> ✔️ >>> <div><a><p></p></a></div> ❌ >>> <span><p></p></span> ❌
Although this combinator does not have its counterpart in CSS, it can be represented as has selector, where child combinator is explicitly stated:
Example
>>> div:has(> p)
It can be created with Anchor instance as well with use of lt operator <:
Example
>>> Anchor < TypeSelector("div")
Notes
RelativeParent selector ignores recursive parameter, as it is always searches only for parent of the anchor element, find_all method can return at most one element (parent).
- class RelativeAncestor(selector: SoupSelector)[source]
Bases:
BaseAncestorSelectorSelector for finding ancestors of the anchor element.
Example
>>> RelativeAncestor(TypeSelector("div"))
when ‘p’ element is passed into find methods:
Example
>>> <div><p></p></div> ✔️ >>> <div><a><p></p></a></div> ✔️ >>> <span><p></p></span> ❌ >>> <p></p><div></div> ❌
Although this combinator does not have its counterpart in CSS, it can be represented as has selector, where descendant combinator is implied:
Example
>>> div:has(p)
It can be created with Anchor instance as well with use of left shift operator <<:
Example
>>> Anchor << TypeSelector("div")
Notes
RelativeAncestor selector ignores recursive parameter, as it is always searches among all ancestors of the anchor element.
- class Anchor_[source]
Bases:
objectShortcut component used to create relative selectors in a more readable way with use of operators.
Anchor_ is an internal class and can be considered a singleton. It’s advisable to use the Anchor instance instead of creating new objects.
Anchor supports the following operators: - >: RelativeChild
Example
>>> Anchor > TypeSelector("div")
Creates RelativeChild selector, that selects any div tag that is a direct child of the tag that is being searched.
>>: RelativeDescendant
Example
>>> Anchor >> TypeSelector("div")
Creates RelativeDescendant selector, that selects any div tag that is a descendant of the tag that is being searched. This is default behavior of selectors, and is equivalent to using the TypeSelector directly, but is implemented for the sake of consistency.
+: RelativeNextSibling
Example
>>> Anchor + TypeSelector("div")
Creates RelativeNextSibling selector, that selects any div tag that is next sibling of the tag that is being searched, it can logically return at most one tag.
*: RelativeSubsequentSibling
Example
>>> Anchor * TypeSelector("div")
Creates RelativeSubsequentSibling selector, that selects any div tag that is a subsequent sibling of the tag that is being searched.
<: RelativeParent
Example
>>> Anchor < TypeSelector("div")
Creates RelativeParent selector, that selects any div tag that is a parent of the tag that is being searched.
<<: RelativeAncestor
Example
>>> Anchor << TypeSelector("div")
Creates RelativeAncestor selector, that selects any div tag that is an ancestor of the tag that is being searched.
This imitates css selector relative selectors that are used for example in :has pseudo-class, that accepts relative selector list as an argument.
Example
>>> :has(> div, + a)
This translated to soupsavvy would be:
Example
>>> HasSelector(Anchor > TypeSelector("div"), Anchor + TypeSelector("a"))
Which would match any tag that has a direct child ‘div’ and a next sibling ‘a’ tag. Selected tag is the anchor tag that is being searched.
Notes
For more information on relative selectors, see:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors/Selector_structure#relative_selector
- class HasSelector(selector: SoupSelector, /, *selectors: SoupSelector)[source]
Bases:
CompositeSoupSelectorSelector for finding elements based on matching reference elements.
Example
>>> HasSelector(TypeSelector("div"))
matches all elements that have any descendant with “div” tag name. It uses default combinator of relative selector, which is descendant combinator.
Example
>>> <span><div>Hello World</div></span> ✔️ >>> <span><a>Hello World</a></span> ❌
Other relative selectors can be used with Anchor element.
Example
… HasSelector(Anchor > TypeSelector(“div”)) … HasSelector(Anchor + TypeSelector(“div”))
or by using RelativeSelector components directly:
Example
… HasSelector(RelativeChild(TypeSelector(“div”))) … HasSelector(RelativeNextSibling(TypeSelector(“div”))
Example
>>> <span><div>Hello World</div></span> ✔️ >>> <span><a><div>Hello World</div></a></span> ❌
In this case, HasSelector is anchored against any element, and matches only elements that have “div” tag name as a child.
This is an equivalent of CSS :has() pseudo-class, that matches element if any of the relative selectors that are passed as an argument match element when anchored against it.
Example
>>> :has(div, a) >>> :has(+ div, > a)
These examples translated to soupsavvy would be:
Example
… HasSelector(TypeSelector(“div”), TypeSelector(“a”)) … HasSelector(Anchor + TypeSelector(“div”), Anchor > TypeSelector(“a”))
Notes
Passing RelativeDescendant selector into HasSelector is equivalent to using its selector directly, as descendant combinator is a default option.
Example
>>> HasSelector(RelativeDescendant(TypeSelector("div"))) ... HasSelector(Anchor > TypeSelector("div")) ... HasSelector(TypeSelector("div"))
Three of the above examples are equivalent.
For more information on :has() pseudo-class, see:
https://developer.mozilla.org/en-US/docs/Web/CSS/:has
- __init__(selector: SoupSelector, /, *selectors: SoupSelector) None[source]
Initializes HasSelector object with provided positional arguments as selectors.
Parameters
- selectors: SoupSelector
SoupSelector objects to match accepted as positional arguments. At least one selector is required to create HasSelector.
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.