2010-01-09 15 views
6

से सीडीएटा कैसे प्राप्त कर सकता हूं मेरे पास एक ऐसी वेबसाइट है जिसे मैं स्क्रैप कर रहा हूं जिसमें निम्न समान संरचना है। मैं सीडीटा ब्लॉक से जानकारी को पकड़ने में सक्षम होना चाहता हूं।मैं सुंदर सूप

मैं पेज से अन्य जानकारी खींचने के लिए सुंदर सूप का उपयोग कर रहा हूं, इसलिए अगर समाधान उसके साथ काम कर सकता है, तो यह मेरे सीखने की वक्र को नीचे रखने में मदद करेगा क्योंकि मैं एक अजगर नौसिखिया हूं। विशेष रूप से, मैं सीडीएटा कथन में छिपा हुआ दो अलग-अलग प्रकार के डेटा प्राप्त करना चाहता हूं। पहला जो सिर्फ पाठ है, मुझे पूरा यकीन है कि मैं उस पर एक रेगेक्स फेंक सकता हूं और मुझे जो चाहिए वह प्राप्त करें। दूसरे प्रकार के लिए, यदि मैं उस डेटा को छोड़ सकता हूं जिसमें HTML तत्वों को अपने स्वयं के सुंदर सूप में रखा गया है, तो मैं इसे पार्स कर सकता हूं।

मैं सिर्फ पाइथन और सुंदरसप सीख रहा हूं, इसलिए मैं जादुई incantation खोजने के लिए संघर्ष कर रहा हूं जो मुझे केवल सीडीएटी देगा।

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

ओच, यह एक बेहद खराब विकृत ब्लॉक है! यदि यह वास्तविक मार्कअप है, तो यह वास्तव में कहीं भी काम नहीं करेगा, न तो एक्सएचटीएमएल और न ही एचटीएमएल ... – bobince

+0

यह वास्तविक नहीं है, मैं बहुत अधिक ब्लॉक को जोड़ना चाहता था। अनुमान है कि मैं बहुत ज्यादा फट गया। –

उत्तर

3

आप इस कोशिश कर सकते:

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] 

है कि आप cdata की सामग्री को देना चाहिए।

अद्यतन

यह एक छोटे से क्लीनर हो सकता है:

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

बस व्यक्तिगत पसंद है, लेकिन मैं नीचे एक थोड़ा बेहतर पसंद है।

+0

प्रतिक्रिया के लिए धन्यवाद, यह वेबसाइट ज्ञान का एक विशाल धन है –

11

सुंदर सूप सीडीटा को "नेविगेट स्ट्रिंग्स" के एक विशेष मामले (उप-वर्ग) के रूप में देखता है। उदाहरण के लिए:

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 

निश्चित रूप से आपके मामले में आप बल्कि दस्तावेज़ पेड़ भर से 'मुख्य-सामग्री' आईडी के साथ div पर शुरू, सबट्री में दिखाई दे सकता है।

+1

धन्यवाद। यह अच्छी तरह से करेगा, यह भी शुरू और अंत बिट्स को साफ कर दिया। मैंने पहले सुंदरSoup.CData की कोशिश की थी, लेकिन यह मेरे लिए काम नहीं किया। मुझे निम्न त्रुटि मिल रही थी: "विशेषताइरर: क्लास सुंदर सूप में कोई विशेषता नहीं है 'सीडीटा' ' अनुमान है कि मुझे" सुंदर सूप आयात सुंदरसूप "के बजाय" सुंदर सुंदरता आयात करें "की आवश्यकता है। –

+1

@ हरी, हां, इस तरह की बात यह है कि मैं हमेशा बिट्स और इसके अंदर से टुकड़ों के बजाय मॉड्यूल ('सुंदर सुंदर सूप' आयात करने की सलाह क्यों देता हूं!) –

+1

ऐसा लगता है कि यह दृष्टिकोण केवल सीडीएटीए टैग के लिए काम करता है टिप्पणी की गई है। मूल प्रश्न के उदाहरण में, सीडीएटीए नहीं मिलेगा। – 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

एक बात आप का उपयोग करते समय BeautifulSoup CDATA lxml पार्सर उपयोग करने के लिए नहीं है हथियाने, डिफ़ॉल्ट रूप से, lxml का पार्सर पेड़ से CDATA भाग पट्टी और उन्हें अपने सादे पाठ सामग्री से बदल देगा की देखभाल करने की आवश्यकता है, और अधिक जानने के यहां 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' 
>>> 
संबंधित मुद्दे