# 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()