def fragments_fromstring(html, no_leading_text=False, base_url=None,
                         parser=None, **kw):
    """
    Parses several HTML elements, returning a list of elements.

    The first item in the list may be a string (though leading
    whitespace is removed).  If no_leading_text is true, then it will
    be an error if there is leading text, and it will always be a list
    of only elements.

    base_url will set the document's base_url attribute (and the tree's docinfo.URL)
    """
    if parser is None:
        parser = html_parser
    # FIXME: check what happens when you give html with a body, head, etc.
    if isinstance(html, bytes):
        if not _looks_like_full_html_bytes(html):
            # can't use %-formatting in early Py3 versions
            html = ('<html><body>'.encode('ascii') + html +
                    '</body></html>'.encode('ascii'))
    else:
        if not _looks_like_full_html_unicode(html):
            html = '<html><body>%s</body></html>' % html
    doc = document_fromstring(html, parser=parser, base_url=base_url, **kw)
    assert _nons(doc.tag) == 'html'
    bodies = [e for e in doc if _nons(e.tag) == 'body']
    assert len(bodies) == 1, ("too many bodies: %r in %r" % (bodies, html))
    body = bodies[0]
    elements = []
    if no_leading_text and body.text and body.text.strip():
        raise etree.ParserError(
            "There is leading text: %r" % body.text)
    if body.text and body.text.strip():
        elements.append(body.text)
    elements.extend(body)
    # FIXME: removing the reference to the parent artificial document
    # would be nice
    return elements
Parses several HTML elements, returning a list of elements.

    The first item in the list may be a string (though leading
    whitespace is removed).  If no_leading_text is true, then it will
    be an error if there is leading text, and it will always be a list
    of only elements.

    base_url will set the document's base_url attribute (and the tree's docinfo.URL)