def get_html_metadata(html):
    """Get metadata dictionary out of HTML object.

    Relevant specs:

    https://www.whatwg.org/html#the-title-element
    https://www.whatwg.org/html#standard-metadata-names
    https://wiki.whatwg.org/wiki/MetaExtensions
    https://microformats.org/wiki/existing-rel-values#HTML5_link_type_extensions

    """
    title = None
    description = None
    generator = None
    keywords = []
    authors = []
    created = None
    modified = None
    attachments = []
    custom = {}
    lang = html.etree_element.attrib.get('lang', None)
    for element in html.wrapper_element.query_all('title', 'meta', 'link'):
        element = element.etree_element
        if element.tag == 'title' and title is None:
            title = get_child_text(element)
        elif element.tag == 'meta':
            name = ascii_lower(element.get('name', ''))
            content = element.get('content', '')
            if name == 'keywords':
                for keyword in map(strip_whitespace, content.split(',')):
                    if keyword not in keywords:
                        keywords.append(keyword)
            elif name == 'author':
                authors.append(content)
            elif name == 'description':
                if description is None:
                    description = content
            elif name == 'generator':
                if generator is None:
                    generator = content
            elif name == 'dcterms.created':
                if created is None:
                    created = parse_w3c_date(name, content)
            elif name == 'dcterms.modified':
                if modified is None:
                    modified = parse_w3c_date(name, content)
            elif name and name not in custom:
                custom[name] = content
        elif element.tag == 'link' and element_has_link_type(
                element, 'attachment'):
            url = get_url_attribute(element, 'href', html.base_url)
            attachment_title = element.get('title', None)
            if url is None:
                LOGGER.error('Missing href in <link rel="attachment">')
            else:
                attachment = Attachment(
                    url=url, description=attachment_title,
                    url_fetcher=html.url_fetcher)
                attachments.append(attachment)
    return {
        'title': title,
        'description': description,
        'generator': generator,
        'keywords': keywords,
        'authors': authors,
        'created': created,
        'modified': modified,
        'attachments': attachments,
        'lang': lang,
        'custom': custom,
    }
Get metadata dictionary out of HTML object.

Relevant specs:

https://www.whatwg.org/html#the-title-element
https://www.whatwg.org/html#standard-metadata-names
https://wiki.whatwg.org/wiki/MetaExtensions
https://microformats.org/wiki/existing-rel-values#HTML5_link_type_extensions
weasyprint/html.py