First Steps

Installation

The easiest way to use tinycss2 is to install it in a Python virtual environment. When your virtual environment is activated, you can then install cssselect2 with pip:

pip install cssselect2

This will also automatically install tinycss2’s only dependencies, tinycss2 and webencodings. cssselect2, tinycss2 and webencodings only contain Python code and should work on any Python implementation.

cssselect2 also is packaged for many Linux distributions (Debian, Ubuntu, Fedora, Archlinux, Gentoo…).

Basic Example

Here is a classical cssselect2 workflow:

  • parse a CSS stylesheet using tinycss2,

  • store the CSS rules in a Matcher object,

  • parse an HTML document using an ElementTree-like parser,

  • wrap the HTML tree in a ElementWrapper object,

  • find the CSS rules matching each HTML tag, using the matcher and the wrapper.

from xml.etree import ElementTree

import cssselect2
import tinycss2

# Parse CSS and add rules to the matcher

matcher = cssselect2.Matcher()

rules = tinycss2.parse_stylesheet('''
  body { font-size: 2em }
  body p { background: red }
  p { color: blue }
''', skip_whitespace=True)

for rule in rules:
    selectors = cssselect2.compile_selector_list(rule.prelude)
    selector_string = tinycss2.serialize(rule.prelude)
    content_string = tinycss2.serialize(rule.content)
    payload = (selector_string, content_string)
    for selector in selectors:
        matcher.add_selector(selector, payload)


# Parse HTML and find CSS rules applying to each tag

html_tree = ElementTree.fromstring('''
  <html>
    <body>
      <p>Test</p>
    </body>
  </html>
''')
wrapper = cssselect2.ElementWrapper.from_html_root(html_tree)
for element in wrapper.iter_subtree():
    tag = element.etree_element.tag.split('}')[-1]
    print('Found tag "{}" in HTML'.format(tag))

    matches = matcher.match(element)
    if matches:
        for match in matches:
            specificity, order, pseudo, payload = match
            selector_string, content_string = payload
            print('Matching selector "{}" ({})'.format(
                selector_string, content_string))
    else:
        print('No rule matching this tag')
    print()