{"id":845,"library":"cssselect","title":"cssselect: CSS Selectors for Python","description":"cssselect is a BSD-licensed Python library that parses CSS3 Selectors and translates them into XPath 1.0 expressions. These XPath expressions can then be used with an XPath engine like lxml to find matching elements in XML or HTML documents. The library is currently at version 1.4.0 and maintains an active development cycle with releases published on PyPI.","status":"active","version":"1.4.0","language":"python","source_language":"en","source_url":"https://github.com/scrapy/cssselect","tags":["css","selectors","xpath","html","xml","parsing","web scraping"],"install":[{"cmd":"pip install cssselect","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"While cssselect generates XPath independently, lxml is the primary library used to execute the generated XPath expressions against HTML/XML documents. Its test suite also requires lxml.","package":"lxml","optional":true}],"imports":[{"symbol":"GenericTranslator","correct":"from cssselect import GenericTranslator"},{"symbol":"HTMLTranslator","correct":"from cssselect import HTMLTranslator"},{"symbol":"SelectorError","correct":"from cssselect import SelectorError"},{"note":"The `css_to_xpath` function is directly available from the top-level `cssselect` package.","wrong":"from cssselect.xpath import css_to_xpath","symbol":"css_to_xpath","correct":"from cssselect import css_to_xpath"},{"symbol":"SelectorSyntaxError","correct":"from cssselect import SelectorSyntaxError"}],"quickstart":{"code":"from lxml.etree import fromstring\nfrom cssselect import HTMLTranslator, SelectorError\n\nhtml_doc = '''\n<div id=\"outer\">\n  <p class=\"content\">\n    <span>Text 1</span>\n  </p>\n  <div id=\"inner\" class=\"content body\">\n    Text 2\n    <span>Text 3</span>\n  </div>\n</div>\n'''\n\ntry:\n    # Use HTMLTranslator for HTML documents for better pseudo-class handling\n    translator = HTMLTranslator()\n    xpath_expression = translator.css_to_xpath('div.content > span')\n    print(f\"Generated XPath: {xpath_expression}\")\n\n    document = fromstring(html_doc)\n    # Find all elements matching the XPath expression\n    matches = document.xpath(xpath_expression)\n\n    for element in matches:\n        print(f\"Matched element tag: {element.tag}, text: {element.text.strip() if element.text else ''}\")\n\nexcept SelectorError as e:\n    print(f\"Invalid CSS selector: {e}\")\n","lang":"python","description":"This quickstart demonstrates how to use `cssselect` to translate a CSS selector into an XPath 1.0 expression and then apply it to an HTML document using `lxml` to find matching elements. It highlights the use of `HTMLTranslator` for HTML-specific translations."},"warnings":[{"fix":"Upgrade Python to version 3.7 or higher.","message":"Version 1.2.0 (released 2022-10-27) dropped support for Python 2.7, 3.4, 3.5, and 3.6. Ensure your environment uses Python 3.7 or newer.","severity":"breaking","affected_versions":">=1.2.0"},{"fix":"For `selector_to_xpath()`, explicitly pass `translate_pseudo_elements=True` if you rely on pseudo-element translation, or `False` to ignore them. Consider using `css_to_xpath()` if pseudo-element behavior is critical and you want consistent default handling.","message":"Between versions 0.9 and 0.9.1, the `selector_to_xpath()` function's default behavior for `translate_pseudo_elements` changed. In 0.9.1+, it defaults to `False` (ignoring pseudo-elements), reverting an accidental change in 0.9 which defaulted to `True` (rejecting them). When using `selector_to_xpath()` directly, explicitly set `translate_pseudo_elements=True` if you need pseudo-element support. `css_to_xpath()` is unaffected.","severity":"breaking","affected_versions":"0.9.x"},{"fix":"Be aware that custom translator subclasses may require updates with new `cssselect` releases. Review the changelog and source code for any changes to the translation API.","message":"The customization API, allowing subclassing of `GenericTranslator` or `HTMLTranslator` to override methods, is not considered stable. Its signature or behavior might change in future versions, potentially breaking your custom subclasses.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Avoid pseudo-elements in selectors intended for XPath 1.0, or be aware of their limited/non-existent translation. If using `selector_to_xpath()`, set `translate_pseudo_elements=True` to attempt translation, but be mindful of XPath 1.0 limitations.","message":"XPath 1.0, which `cssselect` translates to, does not natively support pseudo-elements (e.g., `::before`, `::after`). While `cssselect`'s `css_to_xpath()` provides some translation, `selector_to_xpath()` explicitly ignores them by default. This can lead to unexpected results if pseudo-elements are part of your CSS selectors.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure `lxml` is installed in your Python environment. Typically, `pip install cssselect` should also install `lxml`. If you are installing dependencies manually or in a constrained environment, ensure `pip install lxml` is executed. Note that `lxml` requires compilation tools and development headers on some systems.","message":"The `lxml` library is a required dependency for `cssselect`. If `lxml` is not installed in your Python environment, importing or using `cssselect` will result in a `ModuleNotFoundError`.","severity":"breaking","affected_versions":"All versions"},{"fix":"Install `lxml` in your environment using `pip install lxml` if your project requires it alongside `cssselect`.","message":"The `cssselect` library is frequently used in conjunction with other parsing libraries like `lxml` for HTML/XML processing. If your application or test script uses `lxml` (e.g., for parsing documents), ensure it is explicitly installed. `cssselect` does not list `lxml` as a direct dependency.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T20:20:33.140Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"pip install cssselect","cause":"The cssselect library, although historically integrated with lxml, is now an independent package and needs to be installed separately for lxml's CSS selector functionality to work.","error":"ImportError: cssselect seems not to be installed."},{"fix":"pip install cssselect","cause":"This error occurs when attempting to use the .cssselect() method on an lxml element without the cssselect package being properly installed in the Python environment.","error":"AttributeError: 'lxml.etree._Element' object has no attribute 'cssselect'"},{"fix":"Review the CSS selector for syntax validity, ensuring proper escaping of special characters (e.g., `\\` for colons or periods in names, or quoting attribute values with spaces) and correct adherence to CSS selector grammar.","cause":"The CSS selector string provided contains a syntax error, such as unescaped special characters (e.g., parentheses, colons) in class names or malformed selector patterns, which prevents cssselect from parsing it correctly.","error":"cssselect.parser.SelectorSyntaxError: Expected selector, got <DELIM '(' at ...>"},{"fix":"Simplify the CSS selector to use only features supported by cssselect and XPath 1.0, or consider using direct XPath expressions for complex selections.","cause":"The CSS selector uses a pseudo-class, pseudo-element, or other advanced feature that cssselect cannot translate into a valid XPath 1.0 expression because XPath 1.0 has limitations compared to modern CSS selectors.","error":"cssselect.xpath.ExpressionError: Unknown or unsupported selector (eg. pseudo-class)"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.4.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":"1.3.0","pypi_latest":"1.4.0","is_stale":true,"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"cssselect","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.8,"disk_size":"17.9M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"cssselect","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.8,"disk_size":"17.9M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"cssselect","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.5,"import_time_s":0.01,"mem_mb":0.8,"disk_size":"18M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"cssselect","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.8,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"cssselect","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.05,"mem_mb":1.1,"disk_size":"19.8M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"cssselect","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":1.1,"disk_size":"19.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"cssselect","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0.04,"mem_mb":1.1,"disk_size":"20M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"cssselect","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":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"cssselect","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.04,"mem_mb":0.9,"disk_size":"11.7M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"cssselect","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":0.9,"disk_size":"11.7M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"cssselect","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.4,"import_time_s":0.04,"mem_mb":0.9,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"cssselect","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":0.9,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"cssselect","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.03,"mem_mb":0.9,"disk_size":"11.4M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"cssselect","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":"11.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"cssselect","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.4,"import_time_s":0.03,"mem_mb":0.8,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"cssselect","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":0.8,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"cssselect","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.7,"disk_size":"17.4M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"cssselect","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.7,"disk_size":"17.4M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"cssselect","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.7,"import_time_s":0.01,"mem_mb":0.7,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"cssselect","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.7,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}