web-dev-qa-db-fra.com

BeautifulSoup innerhtml?

Disons que j'ai une page avec un div. Je peux facilement obtenir cette div avec soup.find().

Maintenant que j'ai le résultat, j'aimerais imprimer TOUT innerhtml de div: Je veux dire, j'aurais besoin d'une chaîne avec TOUTES les balises html et du texte tout en avant, exactement comme la chaîne que j'obtiendrais en JavaScript obj.innerHTML. Est-ce possible?

34
Matteo Monti

TL; DR

Avec BeautifulSoup 4, utilisez element.encode_contents() si vous voulez une chaîne de byt codée UTF-8 ou element.decode_contents() si vous voulez une chaîne Python Unicode. Par exemple, la méthode innerHTML du DOM pourrait ressembler à ceci:

def innerHTML(element):
    """Returns the inner HTML of an element as a UTF-8 encoded bytestring"""
    return element.encode_contents()

Ces fonctions ne figurent pas actuellement dans la documentation en ligne, je vais donc citer les définitions de fonctions actuelles et la chaîne de documentation du code.

encode_contents - depuis 4.0.4

def encode_contents(
    self, indent_level=None, encoding=DEFAULT_OUTPUT_ENCODING,
    formatter="minimal"):
    """Renders the contents of this tag as a bytestring.

    :param indent_level: Each line of the rendering will be
       indented this many spaces.

    :param encoding: The bytestring will be in this encoding.

    :param formatter: The output formatter responsible for converting
       entities to Unicode characters.
    """

Voir aussi la documentation sur les formateurs ; vous utiliserez très probablement formatter="minimal" (valeur par défaut) ou formatter="html" (pour les entités html ), sauf si vous souhaitez traiter manuellement le texte.

encode_contents renvoie une chaîne d'octets codée. Si vous voulez une chaîne Python Unicode, utilisez plutôt decode_contents.


decode_contents - depuis 4.0.1

decode_contents fait la même chose que encode_contents mais renvoie une chaîne Python Unicode au lieu d'une chaîne d'octets codée.

def decode_contents(self, indent_level=None,
                   eventual_encoding=DEFAULT_OUTPUT_ENCODING,
                   formatter="minimal"):
    """Renders the contents of this tag as a Unicode string.

    :param indent_level: Each line of the rendering will be
       indented this many spaces.

    :param eventual_encoding: The tag is destined to be
       encoded into this encoding. This method is _not_
       responsible for performing that encoding. This information
       is passed in so that it can be substituted in if the
       document contains a <META> tag that mentions the document's
       encoding.

    :param formatter: The output formatter responsible for converting
       entities to Unicode characters.
    """

BeautifulSoup 3

BeautifulSoup 3 n’a pas les fonctions ci-dessus, mais renderContents 

def renderContents(self, encoding=DEFAULT_OUTPUT_ENCODING,
                   prettyPrint=False, indentLevel=0):
    """Renders the contents of this tag as a string in the given
    encoding. If encoding is None, returns a Unicode string.."""

Cette fonction a été ajoutée à BeautifulSoup 4 ( in 4.0.4 ) pour assurer la compatibilité avec BS3.

40
ChrisD

Une des options pourrait être d'utiliser quelque chose comme ça:

 innerhtml = "".join([str(x) for x in div_element.contents]) 
11
peewhy

Si vous avez seulement besoin du texte (pas de balises HTML), vous pouvez utiliser .text:

soup.select("div").text
2
Pikamander2

Que diriez-vous de unicode(x)? Semble travailler pour moi.

Edit: Ceci vous donnera le code HTML externe et non le code interne.

1
Michael Litvin

Eh bien, vous pouvez aussi utiliser .get_text() pour seulementTEXT

soup.select("div").get_text()
0
Yahyaa