{"id":846,"library":"cssselect2","title":"CSS Selectors for Python ElementTree","description":"cssselect2 is a straightforward implementation of CSS3 and CSS4 Selectors for markup documents (HTML, XML, etc.) that can be read by ElementTree-like parsers (including cElementTree, lxml, and html5lib). Unlike its predecessor `cssselect`, it does not translate selectors to XPath, aiming to resolve correctness issues inherent in that approach. The library is actively maintained, with its current version being 0.9.0, and releases occur several times a year, often coinciding with Python version updates and new CSS selector features.","status":"active","version":"0.9.0","language":"python","source_language":"en","source_url":"https://github.com/Kozea/cssselect2/","tags":["CSS","selectors","ElementTree","HTML","XML","parsing"],"install":[{"cmd":"pip install cssselect2","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required for parsing CSS stylesheets and component values.","package":"tinycss2","optional":false},{"reason":"Required for character encoding detection in HTML parsing contexts.","package":"webencodings","optional":false}],"imports":[{"symbol":"Matcher","correct":"from cssselect2 import Matcher"},{"note":"ElementWrapper should not be instantiated directly. Use `ElementWrapper.from_xml_root()` or `ElementWrapper.from_html_root()` for document roots, and access other elements via wrapper methods like `iter_children()` or `iter_subtree()`.","wrong":"cssselect2.ElementWrapper(etree_element, parent, index, previous, in_html_document)","symbol":"ElementWrapper","correct":"from cssselect2 import ElementWrapper"},{"symbol":"compile_selector_list","correct":"from cssselect2 import compile_selector_list"}],"quickstart":{"code":"from xml.etree import ElementTree\nimport cssselect2\nimport tinycss2\n\n# 1. Parse CSS and add rules to the matcher\nmatcher = cssselect2.Matcher()\ncss_rules = tinycss2.parse_stylesheet('p { color: blue; } body p { background: red; }', skip_whitespace=True)\nfor rule in css_rules:\n    if rule.type == 'qualified-rule': # Handle only actual CSS rules\n        selectors = cssselect2.compile_selector_list(rule.prelude)\n        payload = (tinycss2.serialize(rule.prelude), tinycss2.serialize(rule.content))\n        for selector in selectors:\n            matcher.add_selector(selector, payload)\n\n# 2. Parse HTML and wrap the tree\nhtml_content = '''\n<html>\n<body>\n    <div>\n        <p class=\"intro\">Hello <span>World</span>!</p>\n        <p>Another paragraph.</p>\n    </div>\n</body>\n</html>\n'''\nhtml_tree = ElementTree.fromstring(html_content)\nwrapper = cssselect2.ElementWrapper.from_html_root(html_tree)\n\n# 3. Find CSS rules applying to each tag\nprint('Matching CSS rules:')\nfor element in wrapper.iter_subtree():\n    tag = element.etree_element.tag.split('}')[-1] # Handle namespaces if present\n    matches = matcher.match(element)\n    if matches:\n        print(f'  Tag \"{tag}\" matches:')\n        for match in matches:\n            specificity, order, pseudo_type, payload = match\n            selector_string, content_string = payload\n            print(f'    - Selector: \"{selector_string}\" (Declarations: \"{content_string}\")')\n","lang":"python","description":"This quickstart demonstrates the core workflow of `cssselect2`. It involves parsing a CSS stylesheet using `tinycss2`, compiling its selectors into a `cssselect2.Matcher` object, parsing an HTML document with an ElementTree-like parser, wrapping the root element in `cssselect2.ElementWrapper`, and then iterating through the wrapped elements to find matching CSS rules."},"warnings":[{"fix":"Upgrade your Python environment to a version officially supported by `cssselect2` (e.g., Python 3.10+ for `cssselect2` 0.9.0) before upgrading the library.","message":"Support for older Python versions is regularly dropped. Version 0.9.0 dropped Python 3.9 support, and previous versions (0.8.0, 0.5.0, 0.4.0) have also removed support for Python 3.8, 3.6, and 3.5 respectively. Ensure your environment uses a supported Python version (currently >=3.10 for 0.9.0).","severity":"breaking","affected_versions":"0.4.0, 0.5.0, 0.8.0, 0.9.0"},{"fix":"Replace calls to `element.iter_ancestors()` with `element.ancestors` and `element.iter_previous_siblings()` with `element.previous_siblings`. These are now properties returning tuples.","message":"The `iter_ancestors` and `iter_previous_siblings` methods on `ElementWrapper` were deprecated in version 0.6.0 and removed in 0.7.0. Attempting to call these methods will result in an AttributeError.","severity":"deprecated","affected_versions":"0.6.0, 0.7.0+"},{"fix":"Always use factory methods like `cssselect2.ElementWrapper.from_xml_root(element)` or `cssselect2.ElementWrapper.from_html_root(element)` to create the initial `ElementWrapper` for the document's root element. Other elements should be accessed through the methods provided by the `ElementWrapper` itself (e.g., `iter_children()`, `iter_subtree()`).","message":"When working with `ElementWrapper` objects, it's crucial not to instantiate them directly. Doing so can lead to unexpected behavior and may not correctly establish the necessary parent/sibling relationships for selector matching.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-05-12T20:20:51.900Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"Install the library using pip: `pip install cssselect2`","cause":"The `cssselect2` library has not been installed in the active Python environment.","error":"ModuleNotFoundError: No module named 'cssselect2'"},{"fix":"Review the CSS selector for syntax errors. Ensure the selector adheres to valid CSS selector syntax for selecting elements within a document. For example, `cssselect2` is for selecting elements, not parsing entire CSS stylesheets with directives like `@import`.","cause":"This error occurs when the provided CSS selector string is syntactically incorrect or attempts to use features (like `@import url(...)`) that are not valid for element selection in `cssselect2`.","error":"cssselect2.parser.SelectorError: (<FunctionBlock url( … )>, 'expected a compound selector, got function')"},{"fix":"Ensure `cssselect2` is updated to its latest version (`pip install --upgrade cssselect2`). If directly manipulating `ElementTree` objects, replace deprecated methods like `getiterator()` with the modern `iter()` method.","cause":"This error typically arises when `cssselect2` (or the code interacting with it) is used with `xml.etree.ElementTree` in Python 3.9 or later, where the `getiterator()` method was removed.","error":"AttributeError: 'ElementTree' object has no attribute 'getiterator'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.9.0","cli_name":"","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","installed_version":"0.8.0","pypi_latest":"0.9.0","is_stale":true,"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"cssselect2","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.02,"mem_mb":1.1,"disk_size":"18.3M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"cssselect2","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.1,"disk_size":"18.3M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"cssselect2","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0.01,"mem_mb":1.1,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"cssselect2","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":1.1,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"cssselect2","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.03,"mem_mb":1.1,"disk_size":"20.2M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"cssselect2","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.1,"disk_size":"20.2M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"cssselect2","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.7,"import_time_s":0.03,"mem_mb":1.1,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"cssselect2","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.1,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"cssselect2","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.02,"mem_mb":0.9,"disk_size":"12.0M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"cssselect2","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":0.9,"disk_size":"12.0M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"cssselect2","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0.03,"mem_mb":0.9,"disk_size":"13M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"cssselect2","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.9,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"cssselect2","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.02,"mem_mb":1.1,"disk_size":"11.8M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"cssselect2","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.1,"disk_size":"11.7M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"cssselect2","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0.02,"mem_mb":0.9,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"cssselect2","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.9,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"cssselect2","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.02,"mem_mb":1.1,"disk_size":"17.8M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"cssselect2","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.1,"disk_size":"17.8M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"cssselect2","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.9,"import_time_s":0.01,"mem_mb":1.1,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"cssselect2","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.1,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}