J'ai un site Web que je gratte qui a une structure similaire, ce qui suit. J'aimerais pouvoir saisir l'info du bloc CDATA.
J'utilise BEAUMESUP pour tirer d'autres informations de la page, donc si la solution peut fonctionner avec cela, cela aiderait à garder ma courbe d'apprentissage lorsque je suis un novice Python. Plus précisément, je souhaite obtenir aux deux types de données différents masqués dans la déclaration CDATA. Le premier qui n'est que du texte que je suis sûr que je peux lancer une regex et obtenir ce dont j'ai besoin. Pour le deuxième type, si je pouvais supprimer les données contenant des éléments HTML dans sa propre magnifiqueoupe, je peux analyser cela. P>
Je apprends simplement Python et BeauXoup, alors je me débats pour trouver l'incantation magique qui me donnera juste le CDATA en soi. P>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title> Cows and Sheep </title> </head> <body> <div id="main"> <div id="main-precontents"> <div id="main-contents" class="main-contents"> <script type="text/javascript"> //<![CDATA[var _ = g_cow;_[7654]={cowname_enus:'cows rule!',leather_quality:99,icon:'cow_level_23'};_[37357]={sheepname_enus:'baa breath',wool_quality:75,icon:'sheep_level_23'};_[39654].cowmeat_enus = '<table><tr><td><b class="q4">cows rule!</b><br></br> <!--ts--> get it now<table width="100%"><tr><td>NOW</td><th>NOW</th></tr></table><span>244 Cows</span><br></br>67 leather<br></br>68 Brains <!--yy--> <span class="q0">Cow Bonus: +9 Cow Power</span><br></br>Sheep Power 60 / 60<br></br>Sheep 88<br></br>Cow Level 555</td></tr></table> <!--?5695:5:40:45--> '; //]]> </script> </div> </div> </div> </body> </html>
5 Réponses :
Vous pouvez essayer ceci:
from BeautifulSoup import BeautifulSoup import re // source.html contains your html above f = open('source.html') soup = BeautifulSoup(''.join(f.readlines())) cdata = soup.find(text=re.compile("CDATA"))
Merci pour la réponse, ce site Web est une vaste richesse de connaissances
BelleSoup voit CDATA comme cas particulier (sous-classe) de "chaînes navigables". Donc, par exemple:
import BeautifulSoup txt = '''<foobar>We have <![CDATA[some data here]]> and more. </foobar>''' soup = BeautifulSoup.BeautifulSoup(txt) for cd in soup.findAll(text=True): if isinstance(cd, BeautifulSoup.CData): print 'CData contents: %r' % cd
Merci. Cela fera bien, il a même nettoyé le démarrage et la fin BITS. J'avais déjà essayé Beaulsoup.cdata, mais cela n'a pas fonctionné pour moi. J'avais l'erreur suivante: "AttributeError: la classe BeauXoup n'a pas d'attribut 'CDATA'" suppose que j'avais besoin de "Importer magniformsoup" au lieu de "à partir de la magnifique importation supersoup".
@ Hary, oui, ce genre de chose fait partie de la raison pour laquelle je recommande d'importer toujours le module ( importer beau -soup code>) plutôt que des morceaux de l'intérieur! -)
Il semble que cette approche ne fonctionne que pour les balises CDATA qui n'ont pas été commentées. Dans l'exemple de la question initiale, le CDATA ne serait pas trouvé.
import re from bs4 import BeautifulSoup soup = BeautifulSoup(content) for x in soup.find_all('item'): print re.sub('[\[CDATA\]]', '', x.string)
Par défaut, le parseur LXML dépouillera des sections CDATA de l'arborescence et les remplacera par leur Contenu de texte brut, En savoir plus ici P> < Pré> xxx pré> p>
Pour toute personne utilisant BELLEDUPUP4, la solution de Alex Martelli fonctionne, mais faites ceci:
from bs4 import BeautifulSoup, CData soup = BeautifulSoup(txt) for cd in soup.findAll(text=True): if isinstance(cd, Cdata): print 'CData contents: %r' % cd
Ouch, c'est un bloc de script désespérément malformé! Si c'est le vrai balisage, il ne fonctionnera nulle part où xhtml ni html ...
Ce n'est pas réel, je voulais condenser un bloc beaucoup plus grand. Je suppose que j'ai trop arraché.