History
1.12.1 (2026-09-28)
Fixed memory usage growing with every
xpath()andcss()call when using lxml 5.4.0 or later.
1.12.0 (2026-09-25)
Added support for Python 3.15.
When
typeis not specified,Selectornow detects input as JSON only if it is a JSON object or array. Other valid JSON, such as123or"foo", is now handled as HTML. Passtype="json"to get the old behavior.An explicit
typeis now respected when the input orrootis valid JSON. Before,typewas ignored and the input was handled as JSON. As a result, selectors for text nodes and attribute values whose content is valid JSON, e.g."1", now keep the type of their parent selector instead of"json".When
typeis not specified,bodyis now detected as JSON for any spelling of the UTF-8 encoding name, e.g."UTF-8"or"utf8".When
typeis not specified,Selectornow handles input that starts with an XML declaration (<?xml ...?>) as XML instead of HTML. Passtype="html"to get the old behavior.Fixed
bodyhandling for UTF-16 and other encodings that are not UTF-8: multi-byte characters are no longer garbled, and bytes that the encoding cannot decode are now replaced withU+FFFDinstead of truncating the document.Fixed
SelectorraisingXMLSyntaxErrorfor an XMLbodythat is empty after stripping whitespace and null bytes. It now gets the same empty root as the equivalenttext.Improved performance by caching compiled XPath expressions.
Additional keyword arguments of
xpath()are now always used as XPath variables. Before,extensionsandregexpwere passed to lxml as evaluation options. To use custom XPath functions, register them withparsel.xpathfuncs.set_xpathfunc()instead.Fixed CSS-to-XPath translator instances being kept alive by a translation cache shared by all instances.
xpath(".")now works on selectors for text nodes and attribute values, returning the selector itself instead of an empty list.jmespath()now works on selectors of type"text"and on selectors for text nodes and attribute values.Fixed the CSS
::attr()pseudo-element producing an invalid XPath expression for attribute names that are not valid XPath names, e.g.::attr(foo\:bar).Fixed
drop()on an XML selector also removing the tail text of the dropped element.Fixed
drop()raisingValueErrorinstead ofCannotDropElementWithoutParentfor the root element of an XML selector.Removed the
lxml_version,lxml_huge_tree_versionandLXML_SUPPORTS_HUGE_TREEconstants fromparsel.selector. All supported lxml versions supporthuge_tree.Removed the dependency on
packaging.parsel.utils.iflatten()is now lazy for nested iterables as well.Documented how to extract text, how to use lxml’s
iterlinks(), and how to get the XPath expression of a selector.Removed the link to the unmaintained
parsel-clifrom the documentation.
1.11.0 (2026-01-29)
Removed support for Python 3.9 and PyPy 3.10.
Added support for Python 3.14 and PyPy 3.11.
The following dependencies now have a minimum supported version:
lxml >= 5.1.0packaging >= 23.0jmespath >= 1.0.0
Removed
Selector.remove()andSelectorList.remove(), deprecated in 1.7.0.The
Selector()constructor now acceptsbytearrayvalues for thebodyargument in addition tobytes.attribandremove_namespaces()no longer fail with unhandled exceptions on JSON selectors.Switched the build system to
hatchling.CI fixes and improvements.
1.10.0 (2024-12-16)
Removed support for Python 3.8.
Added support for Python 3.13.
Changed the default encoding name from
"utf8"to"utf-8"everywhere. The former name is not supported in certain environments.CI fixes and improvements.
1.9.1 (2024-04-08)
Removed the dependency on
pytest-runner.Removed the obsolete
Makefile.
1.9.0 (2024-03-14)
Now requires
cssselect >= 1.2.0(this minimum version was required since 1.8.0 but that wasn’t properly recorded)Removed support for Python 3.7
Added support for Python 3.12 and PyPy 3.10
Fixed an exception when calling
__str__or__repr__on some JSON selectorsCode formatted with
blackCI fixes and improvements
1.8.1 (2023-04-18)
Remove a Sphinx reference from NEWS to fix the PyPI description
Add a
twine checkCI check to detect such problems
1.8.0 (2023-04-18)
Add support for JMESPath: you can now create a selector for a JSON document and call
Selector.jmespath(). See the documentation for more information and examples.Selectors can now be constructed from
bytes(using thebodyandencodingarguments) instead ofstr(using thetextargument), so that there is no internal conversion fromstrtobytesand the memory usage is lower.Typing improvements
The
pkg_resourcesmodule (which was absent from the requirements) is no longer usedDocumentation build fixes
New requirements:
jmespathtyping_extensions(on Python 3.7)
1.7.0 (2022-11-01)
Add PEP 561-style type information
Support for Python 2.7, 3.5 and 3.6 is removed
Support for Python 3.9-3.11 is added
Very large documents (with deep nesting or long tag content) can now be parsed, and
Selectornow takes a new argumenthuge_treeto disable thisSupport for new features of cssselect 1.2.0 is added
The
Selector.remove()andSelectorList.remove()methods are deprecated and replaced with the newSelector.drop()andSelectorList.drop()methods which don’t delete text after the dropped elements when used in the HTML mode.
1.6.0 (2020-05-07)
Python 3.4 is no longer supported
New
Selector.remove()andSelectorList.remove()methods to remove selected elements from the parsed document treeImprovements to error reporting, test coverage and documentation, and code cleanup
1.5.2 (2019-08-09)
Selector.remove_namespacesreceived a significant performance improvementThe value of
datawithin the printable representation of a selector (repr(selector)) now ends in...when truncated, to make the truncation obvious.Minor documentation improvements.
1.5.1 (2018-10-25)
has-classXPath function handles newlines and other separators in class names properly;fixed parsing of HTML documents with null bytes;
documentation improvements;
Python 3.7 tests are run on CI; other test improvements.
1.5.0 (2018-07-04)
New
Selector.attribandSelectorList.attribproperties which make it easier to get attributes of HTML elements.CSS selectors became faster: compilation results are cached (LRU cache is used for
css2xpath), so there is less overhead when the same CSS expression is used several times..get()and.getall()selector methods are documented and recommended over.extract_first()and.extract().Various documentation tweaks and improvements.
One more change is that .extract() and .extract_first() methods
are now implemented using .get() and .getall(), not the other
way around, and instead of calling Selector.extract all other methods
now call Selector.get internally. It can be backwards incompatible
in case of custom Selector subclasses which override Selector.extract
without doing the same for Selector.get. If you have such Selector
subclass, make sure get method is also overridden. For example, this:
class MySelector(parsel.Selector):
def extract(self):
return super().extract() + " foo"
should be changed to this:
class MySelector(parsel.Selector):
def get(self):
return super().get() + " foo"
extract = get
1.4.0 (2018-02-08)
SelectorandSelectorListcan’t be pickled because pickling/unpickling doesn’t work forlxml.html.HtmlElement; parsel now raises TypeError explicitly instead of allowing pickle to silently produce wrong output. This is technically backwards-incompatible if you’re using Python < 3.6.
1.3.1 (2017-12-28)
Fix artifact uploads to pypi.
1.3.0 (2017-12-28)
has-classXPath extension function;parsel.xpathfuncs.set_xpathfuncis a simplified way to register XPath extensions;Selector.remove_namespacesnow removes namespace declarations;Python 3.3 support is dropped;
make htmlviewcommand for easier Parsel docs development.CI: PyPy installation is fixed; parsel now runs tests for PyPy3 as well.
1.2.0 (2017-05-17)
Add
SelectorList.getandSelectorList.getallmethods as aliases forSelectorList.extract_firstandSelectorList.extractrespectivelyAdd default value parameter to
SelectorList.re_firstmethodAdd
Selector.re_firstmethodAdd
replace_entitiesargument on.re()and.re_first()to turn off replacing of character entity referencesBug fix: detect
Noneresult from lxml parsing and fallback with an empty documentRearrange XML/HTML examples in the selectors usage docs
Travis CI:
Test against Python 3.6
Test against PyPy using “Portable PyPy for Linux” distribution
1.1.0 (2016-11-22)
Change default HTML parser to lxml.html.HTMLParser, which makes easier to use some HTML specific features
Add css2xpath function to translate CSS to XPath
Add support for ad-hoc namespaces declarations
Add support for XPath variables
Documentation improvements and updates
1.0.3 (2016-07-29)
Add BSD-3-Clause license file
Re-enable PyPy tests
Integrate py.test runs with setuptools (needed for Debian packaging)
Changelog is now called
NEWS
1.0.2 (2016-04-26)
Fix bug in exception handling causing original traceback to be lost
Added docstrings and other doc fixes
1.0.1 (2015-08-24)
Updated PyPI classifiers
Added docstrings for csstranslator module and other doc fixes
1.0.0 (2015-08-22)
Documentation fixes
0.9.6 (2015-08-14)
Updated documentation
Extended test coverage
0.9.5 (2015-08-11)
Support for extending SelectorList
0.9.4 (2015-08-10)
Try workaround for travis-ci/dpl#253
0.9.3 (2015-08-07)
Add base_url argument
0.9.2 (2015-08-07)
Rename module unified -> selector and promoted root attribute
Add create_root_node function
0.9.1 (2015-08-04)
Setup Sphinx build and docs structure
Build universal wheels
Rename some leftovers from package extraction
0.9.0 (2015-07-30)
First release on PyPI.