2010-01-09 19 views
6

Kazıma yaptığım bir web sitem var. CData bloğundan bilgi almak istiyorum.BeautifulSoup'dan CData'yı nasıl yakalarım?

Sayfanın diğer bilgilerini çekmek için BeautifulSoup kullanıyorum, bu yüzden eğer bu çözüm işe yarayabilirse, bir python acemi olduğum için öğrenme eğrimi azaltmaya yardımcı olur. Özellikle, CData deyiminde gizlenen iki farklı veri türüne erişmek istiyorum. sadece metin olan ilk şeyden eminim ki ona bir regex atabilir ve ihtiyacım olanı alabilirim. İkinci tür için, eğer html öğelerine sahip olan verileri kendi güzel formuna bırakabilirsem, onu ayrıştırabilirim.

Ben sadece python ve güzelsoup öğreniyorum, bu yüzden bana sadece CData verecek sihirli büyüyü bulmaya çalışıyorum.

<!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> 
+0

Bu çok kötü biçimlendirilmiş bir komut dosyası bloğu! Bu gerçek işaretleme, aslında XHTML ne de HTML ... – bobince

+0

gerçekte herhangi bir yerde çalışmayacak, çok daha büyük bir bloğu yoğunlaştırmak istedim. sanırım çok fazla yırttım. –

cevap

3

Bu deneyebilirsiniz:

from BeautifulSoup import BeautifulSoup 

// source.html contains your html above 
f = open('source.html') 
soup = BeautifulSoup(''.join(f.readlines())) 
s = soup.findAll('script') 
cdata = s[0].contents[0] 

size cdata içeriğini vermek gerektiğini.

Bu biraz daha temiz olabilir

Güncelleme:

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

Sadece kişisel tercih, ama alt birini biraz daha iyi gibi.

+0

cevabı için teşekkürler, bu web sitesi –

11

BeautifulSoup, CData'yı "gezinilebilir dizelerin" özel bir durumu (alt sınıfı) olarak görür. Bunun yerine belge ağacının her yerinde daha 'ana-içerikleri' kimliğine sahip div başlayan alt ağacındaki görünebilir

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 

elbette durumda örneğin: Yani.

+1

bilginin çok zengin bir servet olduğunu. Bu güzel yapacağım, hatta başlangıç ​​ve bitiş bit temizlendi. Daha önce BeautifulSoup.CData denedim, ama benim için çalışmadı. Aşağıdaki hatayı alıyorum: "AttributeError: class BeautifulSoup" CData "hiçbir özniteliği yoktur" BeautifulSoup import BeautifulSoup "yerine" Import BeautifulSoup "ihtiyacım var" ". –

+1

@hary, evet, bu tür bir şey, her zaman modülün ("Import BeautifulSoup") yerine her zaman içe aktarılmasını tavsiye ederim. -) –

+1

Bu yaklaşım sadece CDATA etiketleri için çalışmıyor. yorumlandı. Orijinal sorunun örneğinde, CDATA bulunamadı. – amergin

0
import re 
from bs4 import BeautifulSoup 

soup = BeautifulSoup(content) 
for x in soup.find_all('item'): 
    print re.sub('[\[CDATA\]]', '', x.string) 
2

tek şey, LXML en çözümleyici ağacından CDATA bölümleri şerit ve düz metin içeriği ile bunları yerini alacak Varsayılan olarak, BeautifulSoup CData Lxml ayrıştırıcı kullanmak değildir kapma kullanırken dikkat olması gerekir, daha fazla bilgi edinmek burada https://groups.google.com/forum/?fromgroups=#!topic/beautifulsoup/whLj3jMRq7g

>>> from bs4 import BeautifulSoup 
>>> import bs4 
>>> s='''<?xml version="1.0" ?> 
<foo> 
    <bar><![CDATA[ 
     aaaaaaaaaaaaa 
    ]]></bar> 
</foo>''' 
>>> soup = BeautifulSoup(s, "html.parser") 
>>> soup.find(text=lambda tag: isinstance(tag, bs4.CData)).string.strip() 
'aaaaaaaaaaaaa' 
>>>