2017-02-02 1 views
2

Compte tenu du code html, comment puis-je supprimer toutes les balises, conserver le texte et img et un balises? Par exemple, jeBeautifulSoup Retirez toutes les balises HTML, sauf pour ceux whitelist tels que « img » et « a » tags avec python

<div><script bla bla></script><p>Hello all <a href ="xx"></a> <img rscr="xx"></img></p></div> 

Je veux garder

Hello to <a href ="xx"></a> <img rscr="xx"></img> 

Y at-il quelque chose mis en œuvre BeautifulSoup ou Python?

Merci

+0

En termes de sécurité est un whitelist mieux! –

Répondre

0

Vous pouvez sélectionner tous les nœuds descendants par accéder au .descendants property.

À partir de là, vous pouvez itérer sur tous les descendants et les filtrer en fonction de la propriété name. Si le noeud n'a pas de propriété name, il s'agit probablement d'un noeud de texte que vous souhaitez conserver. Si la propriété est namea ou img, alors vous le garder ainsi.

# This should be the wrapper that you are targeting 
container = soup.find('div') 
keep = [] 

for node in container.descendants: 
    if not node.name or node.name == 'a' or node.name == 'img': 
    keep.append(node) 

Voici une alternative où tous les éléments filtrés sont utilisés pour créer la liste directement:

# This should be the wrapper that you are targeting 
container = soup.find('div') 

keep = [node for node in container.descendants 
     if not node.name or node.name == 'a' or node.name == 'img'] 

Aussi, si vous ne voulez pas les chaînes qui sont vides à renvoyer, vous pouvez couper les espaces et vérifier que ainsi:

keep = [node for node in container.descendants 
     if (not node.name and len(node.strip())) or 
      (node.name == 'a' or node.name == 'img')] 

Basé sur le HTML que vous avez fourni, ce qui suit seraient renvoyés:

> ['Hello all ', <a href="xx"></a>, <img rscr="xx"/>] 
0
import bs4 

html = '''<div><script bla bla></script><p>Hello all <a href ="xx"></a> <img rscr="xx"></img></p></div>''' 

soup = bs4.BeautifulSoup(html, 'lxml') 
soup.div.text, soup.div.find_next('a'), soup.div.find_next('img') 

sur:

('Hello all ', <a href="xx"></a>, <img rscr="xx"/>) 

Lorsque l'élément suivant est le descendant de la balise, il existe un raccourci:

soup.div.text, soup.div.a, soup.div.img 

sur:

('Hello all ', <a href="xx"></a>, <img rscr="xx"/>) 
  1. lorsque vous utilisez l'analyseur de BS4, balise « img » sera étiquette auto-fermée
  2. Vous pouvez aways utiliser find_next pour obtenir l'élément suivant dans les DOM
+0

et si j'avais "

Hello all

" ??? Votre code ne donne que le premier tag trouvé qu'il rencontre ... la chaîne n'était qu'un exemple, j'ai besoin d'analyser une page web entière. – f126ck

+0

@ f126ck mettre à jour votre question avec l'URL et la sortie que vous voulez –