web-dev-qa-db-fra.com

BeautifulSoup: il suffit d'entrer dans une balise, quel que soit le nombre de balises qui l'entourent

J'essaie d'extraire tout le code HTML interne des éléments <p> d'une page Web à l'aide de BeautifulSoup. Il y a des tags internes, mais je m'en fiche, je veux juste obtenir le texte interne.

Par exemple, pour:

<p>Red</p>
<p><i>Blue</i></p>
<p>Yellow</p>
<p>Light <b>green</b></p>

Comment puis-je extraire:

Red
Blue
Yellow
Light green

Ni .string ni .contents[0] ne fait ce dont j'ai besoin. .extract() non plus, parce que je ne veux pas avoir à spécifier les balises internes à l'avance - je veux gérer toutes les éventualités.

Existe-t-il un type de méthode "récupère uniquement le code HTML visible" dans BeautifulSoup?

----METTRE À JOUR------

Sur le conseil, essayez:

soup = BeautifulSoup(open("test.html"))
p_tags = soup.findAll('p',text=True)
for i, p_tag in enumerate(p_tags): 
    print str(i) + p_tag

Mais cela n'aide pas - cela affiche:

0Red
1

2Blue
3

4Yellow
5

6Light 
7green
8
37
AP257

Réponse courte: soup.findAll(text=True)

Ceci a déjà été répondu, ici sur StackOverflow et dans la documentation BeautifulSoup .

METTRE À JOUR:

Pour clarifier, un morceau de code de travail:

>>> txt = """\
<p>Red</p>
<p><i>Blue</i></p>
<p>Yellow</p>
<p>Light <b>green</b></p>
"""
>>> import BeautifulSoup
>>> BeautifulSoup.__version__
'3.0.7a'
>>> soup = BeautifulSoup.BeautifulSoup(txt)
>>> for node in soup.findAll('p'):
    print ''.join(node.findAll(text=True))

Red
Blue
Yellow
Light green
66
taleinat

La réponse acceptée est excellente mais elle a maintenant 6 ans. Voici donc la version actuelle de Beautiful Soup 4 de cette réponse:

>>> txt = """\
<p>Red</p>
<p><i>Blue</i></p>
<p>Yellow</p>
<p>Light <b>green</b></p>
"""
>>> from bs4 import BeautifulSoup, __version__
>>> __version__
'4.5.1'
>>> soup = BeautifulSoup(txt, "html.parser")
>>> print("".join(soup.strings))

Red
Blue
Yellow
Light green
11
Jaymon

Normalement, les données extraites du site Web contiennent des balises. Pour éviter ces balises et afficher uniquement du contenu texte, vous pouvez utiliser un attribut texte.

Par exemple,

    from BeautifulSoup import BeautifulSoup

    import urllib2 
    url = urllib2.urlopen("https://www.python.org")

    content = url.read()

    soup = BeautifulSoup(content)

    title = soup.findAll("title")

    paragraphs = soup.findAll("p")

    print paragraphs[1] //Second paragraph with tags

    print paragraphs[1].text //Second paragraph without tags

Dans cet exemple, je collecte tous les paragraphes du site python et les affiche avec des balises et sans balises.

2
Codemaker

Commencez par convertir le code HTML en chaîne à l'aide de str. Ensuite, utilisez le code suivant avec votre programme:

import re
x = str(soup.find_all('p'))
content = str(re.sub("<.*?>", "", x))

Ceci s'appelle une regex. Celui-ci supprimera tout ce qui se trouve entre deux balises HTML (y compris les balises).

0
toyotasupra