2011-12-25 14 views
5

मैं जंगली वेब से मनमाने ढंग से दस्तावेजों को डाउनलोड करने की कोशिश कर रहा हूं, और हाँ, मेरे पास उनकी सामग्री का कोई नियंत्रण नहीं है।सुंदर सूप यूनिकोड एन्कोडररर "रेंज (128)"

Beautiful Soup won't choke if you give it bad markup... के बाद से मुझे आश्चर्य है कि क्यों यह मुझे उन देहाती अप दे रही है जब कभी कभी, दस्तावेज़ के हिस्सा विकृत है, और वहाँ यह दस्तावेज़ के अगले पठनीय हिस्से को फिर से शुरू, इस पर ध्यान दिए बिना बनाने के लिए एक तरीका है कि क्या त्रुटि।

लाइन जहां त्रुटि 3 एक हुआ है:

from BeautifulSoup import BeautifulSoup as doc_parser 
reader = open(options.input_file, "rb") 
doc = doc_parser(reader) 

CLI पूर्ण उत्पादन होता है:

Traceback (most recent call last): 
    File "./grablinks", line 101, in <module> 
    sys.exit(main()) 
    File "./grablinks", line 88, in main 
    links = grab_links(options) 
    File "./grablinks", line 36, in grab_links 
    doc = doc_parser(reader) 
    File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1519, in __init__ 
    BeautifulStoneSoup.__init__(self, *args, **kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1144, in __init__ 
    self._feed(isHTML=isHTML) 
    File "/usr/local/lib/python2.7/dist-packages/BeautifulSoup.py", line 1186, in _feed 
    SGMLParser.feed(self, markup) 
    File "/usr/lib/python2.7/sgmllib.py", line 104, in feed 
    self.goahead(0) 
    File "/usr/lib/python2.7/sgmllib.py", line 143, in goahead 
     k = self.parse_endtag(i) 
    File "/usr/lib/python2.7/sgmllib.py", line 320, in parse_endtag 
    self.finish_endtag(tag) 
    File "/usr/lib/python2.7/sgmllib.py", line 358, in finish_endtag 
    method = getattr(self, 'end_' + tag) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 15-16: ordinal not in range(128) 
+0

आप सुंदर सूप को किस तरह का इनपुट खिला रहे हैं? त्रुटि संदेश के मुताबिक, हो सकता है कि आप कुछ गैर-असीसी डेटा पार्स कर रहे हों (उदाहरण के लिए गैर-लैटिन वर्ण हैं)? –

+0

मैं पार्सिंग डेटा जंगली वेब से आता हूं, और इसके कुछ हिस्से निश्चित रूप से गैर-असीसी हैं। –

उत्तर

2

हाँ, यदि आपके पास गैर-ASCII नामों (<café>) वाले तत्व हैं तो यह चकित होगा। और यह एक्सएमएल के लिए भी 'खराब मार्कअप' नहीं है ...

यह sgmllib में एक बग है जो सुंदरसप का उपयोग कर रहा है: यह टैग के समान नामों के साथ कस्टम विधियों को खोजने का प्रयास करता है, लेकिन पायथन 2 विधि नाम बाइट तार हैं इसलिए गैर-ASCII वर्ण वाली विधि के लिए देख रहा है, जो कभी भी मौजूद नहीं होगा, विफल रहता है।

आप except AttributeError: से except AttributeError, UnicodeError: से लाइन 25 9 और 371 को बदलकर sgmllib में एक फिक्स हैक कर सकते हैं लेकिन यह वास्तव में एक अच्छा फिक्स नहीं है। बाकी विधि को ओवरराइड करने के लिए तुच्छ नहीं है।

क्या आप पार्स करने की कोशिश कर रहे हैं? सुंदरस्टोन सूप हमेशा संदिग्ध उपयोगिता का था-एक्सएमएल में एचटीएमएल की भयानक पार्सर हैक्स की संपत्ति नहीं है, इसलिए सामान्य टूटा एक्सएमएल एक्सएमएल नहीं है। नतीजतन आपको आम तौर पर एक सादे पुराने एक्सएमएल पार्सर का उपयोग करना चाहिए (उदाहरण के लिए एक मानक डोम या एट्री का उपयोग करें)। सामान्य एचटीएमएल पार्सिंग के लिए, html5lib इन दिनों आपका बेहतर विकल्प है।

+0

आपके द्वारा सुझाए गए फ़िक्स वास्तव में बिल्कुल काम नहीं करेंगे, क्योंकि त्रुटि वास्तव में पहले शुरू होती है, जब पार्सर एक regexp का उपयोग करके _start_ टैग से मेल खाता है जो केवल गैर-असीसी वर्णों का समर्थन करता है। इसका मतलब है कि 'यूनिकोड एन्कोड एरर' होने से पहले एक मान्य प्रारंभ टैग छोड़ा जाएगा। – ekhumoro

+0

@bobince, मैंने आपके सुझाव का पालन किया और * यूनिकोड एरर', 'यूनिकोड एन्कोडरर' और 'यूनिकोडडेकोड एरर'' (https://gist.github.com/1520499#L331 पर देखें) * _endtag और * _startag विधियों के लिए - और अब मेरे पास है परिणाम जो मैंने अपेक्षित हैं, यह केवल बाइनरी भागों को छोड़ देता है और केवल प्रासंगिक हिस्सों को निकालता है। धन्यवाद! –

0

यह तब होता है, अगर वहाँ अजगर संस्करणों में इनपुट से पहले में गैर- ASCII वर्ण हैं पायथन 3.0

यदि आप चार मान> 128 (ANSII & यूनिकोड) के साथ वर्ण युक्त स्ट्रिंग पर str(...) का उपयोग करने का प्रयास कर रहे हैं, तो यह अपवाद आर है aised।

यहाँ, त्रुटि संभवतः इसलिए होती है क्योंकि getattr की कोशिश करता एक यूनिकोड स्ट्रिंग पर str उपयोग करने के लिए - यह "सोचता है कि" इसे सुरक्षित रूप से इस वजह से अजगर संस्करणों में पहले 3.0 पहचानकर्ता को यूनिकोड शामिल नहीं करना चाहिए कर सकते हैं।

यूनिकोड वर्णों के लिए अपना HTML देखें। इन्हें प्रतिस्थापित/एन्कोड करने का प्रयास करें और यदि यह अभी भी काम नहीं करता है, तो हमें बताएं।

संबंधित मुद्दे