web-dev-qa-db-fra.com

Génération de documents HTML en python

En python, quelle est la façon la plus élégante de générer des documents HTML. J'ajoute actuellement manuellement toutes les balises à une chaîne géante et l'écris dans un fichier. Existe-t-il une manière plus élégante de procéder?

56
shoes

Je trouve que yattag est la façon la plus élégante de le faire.

from yattag import Doc

doc, tag, text = Doc().tagtext()

with tag('html'):
    with tag('body'):
        with tag('p', id = 'main'):
            text('some text')
        with tag('a', href='/my-url'):
            text('some link')

result = doc.getvalue()

Il se lit comme du HTML, avec l'avantage supplémentaire que vous n'avez pas à fermer les balises.

46

Je suggère d'utiliser l'un des nombreux langages de modèles disponibles pour python, par exemple celui intégré à Django (vous n'avez pas besoin d'utiliser le reste de Django to utiliser son moteur de modèles) - une requête Google devrait vous donner beaucoup d'autres implémentations de modèles alternatifs.

Je trouve que l'apprentissage d'une bibliothèque de modèles aide à bien des égards - chaque fois que vous devez générer un e-mail, une page HTML, un fichier texte ou similaire, il vous suffit d'écrire un modèle, de le charger avec votre bibliothèque de modèles, puis de laisser le code du modèle créer le produit fini.

Voici un code simple pour vous aider à démarrer:

#!/usr/bin/env python

from Django.template import Template, Context
from Django.conf import settings
settings.configure() # We have to do this to use Django templates standalone - see
# http://stackoverflow.com/questions/98135/how-do-i-use-Django-templates-without-the-rest-of-Django

# Our template. Could just as easily be stored in a separate file
template = """
<html>
<head>
<title>Template {{ title }}</title>
</head>
<body>
Body with {{ mystring }}.
</body>
</html>
"""

t = Template(template)
c = Context({"title": "title from code",
             "mystring":"string from code"})
print t.render(c)

C'est encore plus simple si vous avez des modèles sur le disque - consultez la fonction render_to_string pour Django 1.7 qui peut charger des modèles à partir du disque à partir d'une liste prédéfinie de chemins de recherche, remplissez avec données d'une dictée et rendu dans une chaîne - tout en un appel de fonction. (supprimé de Django 1.8 activé, voir Engine.from_string pour une action comparable)

30
Erik Forsberg

Si vous créez des documents HTML, je vous suggère fortement d'utiliser un système de modèles (comme jinja2 ) comme d'autres l'ont suggéré. Si vous avez besoin d'une génération de bas niveau de bits html (peut-être en tant qu'entrée dans l'un de vos modèles), alors le package xml.etree est un package python standard et pourrait adapter le projet de loi bien.

import sys
from xml.etree import ElementTree as ET

html = ET.Element('html')
body = ET.Element('body')
html.append(body)
div = ET.Element('div', attrib={'class': 'foo'})
body.append(div)
span = ET.Element('span', attrib={'class': 'bar'})
div.append(span)
span.text = "Hello World"

if sys.version_info < (3, 0, 0):
  # python 2
  ET.ElementTree(html).write(sys.stdout, encoding='utf-8',
                             method='html')
else:
  # python 3
  ET.ElementTree(html).write(sys.stdout, encoding='unicode',
                             method='html')

Imprime ce qui suit:

<html><body><div class="foo"><span class="bar">Hello World</span></div></body></html>
7
cheshirekow

Je recommanderais d'utiliser xml.dom pour ce faire.

http://docs.python.org/library/xml.dom.html

Lisez cette page de manuel, elle a des méthodes pour construire XML (et donc XHTML). Il facilite toutes les tâches XML, y compris l'ajout de nœuds enfants, les types de documents, l'ajout d'attributs, la création de nœuds de texte. Cela devrait pouvoir vous aider dans la grande majorité des choses que vous ferez pour créer du HTML.

Il est également très utile pour analyser et traiter les documents xml existants.

J'espère que cela t'aides

P.S

Voici un tutoriel qui devrait vous aider à appliquer la syntaxe

http://www.postneo.com/projects/pyxml/

6
Sheik Yerbouti

J'utilise l'extrait de code appelé throw_out_your_templates pour certains de mes propres projets:

https://github.com/tavisrudd/throw_out_your_templates

https://bitbucket.org/tavisrudd/throw-out-your-templates/src

Malheureusement, il n'y a pas de package pypi pour cela et il ne fait partie d'aucune distribution car il ne s'agit que d'une preuve de concept. Je n'ai pas non plus pu trouver quelqu'un qui a pris le code et a commencé à le maintenir en tant que projet réel. Néanmoins, je pense que cela vaut la peine d'essayer même si cela signifie que vous devez expédier votre propre copie de throw_out_your_templates.py avec votre code.

Semblable à la suggestion d'utiliser yattag par John Smith facultatif, ce module ne vous oblige pas à apprendre un langage de modèle et s'assure également que vous n'oublierez jamais de fermer les balises ou de citer des caractères spéciaux. Tout reste écrit en Python. Voici un exemple d'utilisation:

html(lang='en')[
  head[title['An example'], meta(charset='UTF-8')],
  body(onload='func_with_esc_args(1, "bar")')[
      div['Escaped chars: ', '< ', u'>', '&'],
      script(type='text/javascript')[
           'var lt_not_escaped = (1 < 2);',
           '\nvar escaped_cdata_close = "]]>";',
           '\nvar unescaped_ampersand = "&";'
          ],
      Comment('''
      not escaped "< & >"
      escaped: "-->"
      '''),
      div['some encoded bytes and the equivalent unicode:',
          '你好', unicode('你好', 'utf-8')],
      safe_unicode('<b>My surrounding b tags are not escaped</b>'),
      ]
  ]
2
josch