'Convenience method to take a
`BeautifulSoup <https://www.crummy.com/software/BeautifulSoup/bs3/documentation.html>`_
`Tag` and extract the text from it recursively, including any CDATA sections
and alt tag attributes. Return a possibly empty unicode string.
`use_alt`: If `True` try to use the alt attribute for tags that don\'t
have any textual content
`tag`: `BeautifulSoup <https://www.crummy.com/software/BeautifulSoup/bs3/documentation.html>`_
`Tag`'

@classmethod
def tag_to_string(self, tag, use_alt=True, normalize_whitespace=True):

    if (tag is None):
        return ''
    if isinstance(tag, basestring):
        return tag
    if (callable(getattr(tag, 'xpath', None)) and (not hasattr(tag, 'contents'))):
        from lxml.etree import tostring
        ans = tostring(tag, method='text', encoding=unicode, with_tail=False)
    else:
        strings = []
        for item in tag.contents:
            if isinstance(item, (NavigableString, CData)):
                strings.append(item.string)
            elif isinstance(item, Tag):
                res = self.tag_to_string(item)
                if res:
                    strings.append(res)
                elif use_alt:
                    try:
                        strings.append(item['alt'])
                    except KeyError:
                        pass
        ans = u''.join(strings)
    if normalize_whitespace:
        ans = re.sub('\\s+', '    ', ans)
    return ans
