def _parse_element(self, elt, parent_is_keep=False):
        """
        Parses an Element recursively

        :param elt: HtmlElement to parse
        :type elt: lxml.html.HtmlElement
        :param parent_is_keep: Whether the element is inside a keep element or not
        :type parent_is_keep: bool
        """
        for e in elt.iterchildren():

            is_discard_element = self._is_discard(e)
            is_keep_element = self._is_keep(e)

            # Element is an explicit one to discard, flag it and continue
            if is_discard_element and not is_keep_element:
                self.elts_to_remove.append(e)
                continue

            if not parent_is_keep:
                # Parent element is not an explicit keep, normal process
                # Element is an explicit one to keep, inspect it
                if is_keep_element:
                    self._parse_element(e, parent_is_keep=True)
                    continue

                # Has a descendant to keep, inspect it
                if self._has_keep_elt_in_descendants(e):
                    self._parse_element(e)
                    continue

                # Element did not match anything, remove it
                self.elts_to_remove.append(e)

            else:
                # Element is a child of a keep element, only check explicit discards
                self._parse_element(e, parent_is_keep=True)
Parses an Element recursively

        :param elt: HtmlElement to parse
        :type elt: lxml.html.HtmlElement
        :param parent_is_keep: Whether the element is inside a keep element or not
        :type parent_is_keep: bool