NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #98 most downloaded on PyPI
A modern CSS selector implementation for Beautiful Soup.
Last release 10 days ago
24 Sep 2026
Release timing varies
gaps range from 3 weeks to 12 months
Nearly every release is documented
notes for 53 of 54 stable releases
Nothing withdrawn
no release was ever pulled
8 years old
56 releases · first in 2018
NEW : Add new ignore option to API methods that allows the specification of specific pseudo-classes to be ignored.
ignore option to API methods that allows the specification of specific pseudo-classes to benamespaces and custom objects must always be a Mapping, previously listsNull of type SelectorNull.NOCACHE flag that can be used to disable caching optimizations selectors and possibly other future~ for various cases by employing caching.nth-* family of selectors in certain scenarios by employing caching.custom is properly passed down from API functions to compilation.One column per quarter.
FIX : Fix issue where :is() and :where() were not accounting for empty selectors in the max selector count as they should ( @arpitjain099 ).
:is() and :where() were not accounting for empty selectors in the max selector count as:has() was allowing empty selectors in some circumstances even though it is not:is() and :where() contain empty selectors.FIX : Correct [attr^=""] , [attr$=""] , and [attr*=""] to match nothing when the value is empty, per CSS Selectors Level 4 substring matching, which p
[attr^=""], [attr$=""], and [attr*=""] to match nothing when the value is empty, per CSSNEW : Lazy compile selector patterns to improve initial import speed.
:nth-child/:nth-of-type (and -last- variants) for An+B values whose sequence steps onto:nth-child(2n-2), :nth-child(n-1), :nth-child(n+5)), which previouslyFIX : Fix another inefficient attribute pattern ( @mauriceng98 ).
FIX : Fix inefficient attribute pattern.
FIX : Ensure custom selectors or namespace dictionaries reject non-string keys ( @mundanevision20 ).
:in-range and :out-of-range with end of year weeks (@mundanevision20).FIX : Changes in tests to accommodate latest Python HTML parser changes.
NEW : Drop support for Python 3.8.
NEW : Add :open pseudo selector.
:open pseudo selector.:muted pseudo selector.:autofill, :buffering, :fullscreen, :picture-in-picture,:popover-open, :seeking, :stalled, and :volume-locked. These selectors, while recognized, will not match anyNEW : Add official support for Python 3.13.
& as scoping root per the CSS Nesting Module, Level 1. When & is used outside the:scope).NEW: Update to support Python 3.12.
FIX: Attribute syntax for case insensitive flag optionally allows a space, it does not require one.
NEW: Update to support changes related to :lang() in the official CSS spec. :lang("") should match unspecified languages, e.g. lang="", but not lang=u
:lang() in the official CSS spec. :lang("") should match unspecified
languages, e.g. lang="", but not lang=und.:is() and :where() should allow forgiving selector lists according to latest CSS (as far as Soup
Sieve supports "forgiving" which is limited to empty selectors).FIX: Documentation for installation from source is outdated.
FIX: Fix some typos in error messages.
FIX: Ensure attribute selectors match tags that have new lines characters in attributes.
NEW: Officially support Python 3.10.
:has(), :is(), and :where() now use use a forgiving selector list. While not as forgiving as CSS might
be, it will forgive such things as empty sets and empty slots due to multiple consecutive commas, leading commas, or
trailing commas. Essentially, these pseudo-classes will match all non-empty selectors and ignore empty ones. As the
scraping environment is different than a browser environment, it was chosen not to aggressively forgive bad syntax and
invalid features to ensure the user is alerted that their program may not perform as expected.SelectorList for debug purposes.FIX: Fix an issue with namespaces when one of the keys is self.
self.NEW: :link and :any-link no longer include due to a change in the level 4 selector specification. This actually yields more sane results.
:link and :any-link no longer include <link> due to a change in the level 4 selector specification. This actually yields more sane results.find, is quite forgiving of odd types that a user may place in an element's attribute value. Soup Sieve will also now be more forgiving and attempt to match these unexpected values in a sane manner by normalizing them before compare. (#212)As a consequence, :contains() will now be known as :-soup-contains(), though for a time the deprecated form of :contains() will still be allowed with…
:-soup- prefix. As a consequence, :contains() will now be known as :-soup-contains(), though
for a time the deprecated form of :contains() will still be allowed with a warning that users should migrate over
to :-soup-contains().:-soup-contains-own() which operates similar to :-soup-contains()
except that it only looks at text nodes directly associated with the currently scoped element and not its
descendants.bs4 globally instead of in local functions as it appears there are no adverse affects due to
circular imports as bs4 does not immediately reference soupsieve functions and soupsieve does not immediately
reference bs4 functions. This should give a performance boost to functions that had previously included bs4
locally.## 2.0.1 - FIX: Remove unused code.
NEW: Remove deprecated comments and icomments from the API.
SelectorSyntaxError is derived from Exception not SyntaxError.comments and icomments from the API.|.Note: Last version for Python 2.7
Note: Last version for Python 2.7
|.FIX: :placeholder-shown should not match if the element has content that overrides the placeholder.
:placeholder-shown should not match if the element has content that overrides the placeholder.FIX: :checked rule was too strict with option elements. The specification for :checked does not require an option element to be under a select element
:checked rule was too strict with option elements. The specification for :checked does not require an
option element to be under a select element.:lang() wildcard match handling with singletons. Implicit wildcard matching should not
match any singleton. Explicit wildcard matching (* in the language range: *-US) is allowed to match singletons.FIX: [attr!=value] pattern was mistakenly using :not([attr|=value]) logic instead of :not([attr=value]).
[attr!=value] pattern was mistakenly using :not([attr|=value]) logic instead of :not([attr=value])._QUIRKS mode flag. Beautiful Soup was meant to use it to help with transition to Soup Sieve, but never released with it. Help with transition at this point is no longer needed.FIX: Shortcut last descendant calculation if possible for performance.
Doctype strings can be mistaken for a normal text node in some cases.:root tag if it has sibling text nodes or tag nodes. This is an issue that mostly manifests when using html.parser as the parser will allow multiple root nodes.FIX: :root, :contains(), :default, :indeterminate, :lang(), and :dir() will properly account for HTML iframe elements in their logic when selecting or
:root, :contains(), :default, :indeterminate, :lang(), and :dir() will properly account for HTML iframe elements in their logic when selecting or matching an element. Their logic will be restricted to the document for which the element under consideration applies.NEW: Deprecate comments and icomments functions in the API to ensure Soup Sieve focuses only on CSS selectors. comments and icomments will most likely…
:contains() to accept a list of text to search for. (#115)escape function for escaping CSS identifiers. (#125)comments and icomments functions in the API to ensure Soup Sieve focuses only on CSS
selectors. comments and icomments will most likely be removed in 2.0. (#130)soupsieve package. (#111):contains() comparison.U+FFFD) according to the
specification. This applies to CSS escaped NULL characters as well. (#124)U+FFFD outside of CSS strings. In a string, they should just be ignored,
but as there is no case where we could resolve such a string and still have a valid selector, string handling
remains the same. (#128)NEW: Add custom selector support.
-. (#107)\r\n as a single character, especially in cases
such as string escapes: \\\r\n. (#107)-- as a valid identifier or identifier start. (#107)SelectorSyntaxError, which is still currently derived from SyntaxError, but
will most likely be derived from Exception in the future.FIX: Fix regression with tag names in regards to case sensitivity, and ensure there are tests to prevent breakage in the future.
FIX: Fix HTML detection for type selector.
type selector.:enabled and :disabled.FIX: Fix issue with :has() selector where a leading combinator can only be provided in the first selector in a relative selector list.
:has() selector where a leading combinator can only be provided in the first selector in a relative selector list.NEW: Add support for :in-range and :out-of-range selectors.
:in-range and :out-of-range selectors. (#60):defined selector. (#76)NullSelector object. (#70):nth-* patterns were converting numbers to base 16 when they should have been converting to base 10.FIX: Fix pattern compile issues on Python < 2.7.4.
\d in Unicode Re patterns as they will contain characters outside the range of [0-9].FIX: Fix warning about not importing Mapping from collections.abc.
Mapping from collections.abc.NEW: Add closest method to the API that matches closest ancestor.
closest method to the API that matches closest ancestor.select_one reference to module's __all__.NEW: Add select_one method like Beautiful Soup has.
select_one method like Beautiful Soup has.:dir() selector (HTML only).BeautifulSoup object as a parent).nth range check.Nothing published for this version
FIX: Fix issue with undefined namespaces.
NEW: :user-invalid, :playing, :paused, and :local-link will not cause a failure, but all will match nothing as their use cases are not possible in an
:scope.:user-invalid, :playing, :paused, and :local-link will not cause a failure, but all will match
nothing as their use cases are not possible in an environment outside a web browser.[attr~=value] handling of whitespace. According to the spec, if the value contains whitespace, or is
an empty string, it should not match anything.FIX: More descriptive exceptions. Exceptions will also now mention position in the pattern that is problematic.
filter ignores NavigableString objects in normal iterables and Tag iterables. Basically, it filters all Beautiful Soup document parts regardless of iterable type where as it used to only filter out a NavigableString in a Tag object. This is viewed as fixing an inconsistency.DEBUG flag has been added to help with debugging CSS selector parsing. This is mainly for development.meta tag, and no language is found, cache that there is no language in the meta tag to prevent searching again during the current select.BeautifulSoup/Tag object is given to the API to compare against, raise a TypeError.NEW: Remove old pre 1.0 deprecations.
NEW: Adds support for [attr!=value] which is equivalent to :not([attr=value]).
[attr!=value] which is equivalent to :not([attr=value]).:active, :focus, :hover, :visited, :target, :focus-within, :focus-visible,
:target-within, :current()/:current, :past, and :future, but they will never match as these states don't
exist in the Soup Sieve environment.:checked, :enabled, :disabled, :required, :optional, :default, and
:placeholder-shown which will only match in HTML documents as these concepts are not defined in XML.:link and :any-link, both of which will target all <a>, <area>, and <link>
elements with an href attribute as all links will be treated as unvisited in Soup Sieve.:lang() (CSS4) which works in XML and HTML.prefix:attr can be matched with the form [prefix\:attr] without specifying a
namespaces if desired.[type] is used (with no value).FIX: Use proper CSS identifier patterns for tag names, classes, ids, etc. Things like #3 or #-3 should not match and should require #\33 or #-\33.
#3 or #-3 should not match and should require #\33 or #-\33.NotImplementedError for supported pseudo classes/elements with bad syntax, instead raise SyntaxError.FIX: When giving a tag to select, it should only return the children of that tag, never the tag itself.
select, it should only return the children of that tag, never the tag itself.NotImplementedError when an unsupported pseudo class is used.- NEW: Official 1.0.0 release.
Nothing published for this version
Nothing published for this version
NEW: mode attribute is now called flags to allow for other options in the future.
mode attribute is now called flags to allow for other options in the future.nth selectors.FIX: Previously, all pseudo classes' selector lists were evaluated as one big group, but now each pseudo classes' selector lists are evaluated separat
FIX: Add missing s flag to attribute selector for forced case sensitivity of attribute values.
s flag to attribute selector for forced case sensitivity of attribute values.type attribute in HTML is handled special. While all other attributes values are case sensitive, type in HTML is usually treated special and is insensitive. In XML, this is not the case.FIX: Fix namespace check for :nth-of-type.
:nth-of-type.NEW: Deprecate commentsiter and selectiter in favor of icomments and iselect. Expect removal in version 1.0.
commentsiter and selectiter in favor of icomments and iselect. Expect removal in version
1.0.- NEW: Initial prerelease.
Your coding agent can read these notes before it upgrades. Set up the MCP server →