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
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
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
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.
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).