2010-01-27 14 views
20

क्या कोई जानता है कि पाइथन में फ़ाइल के एन्कोडिंग को कैसे प्राप्त किया जाए। मुझे पता है कि आप एक विशिष्ट एन्कोडिंग के साथ फ़ाइल खोलने के लिए कोडेक्स मॉड्यूल का उपयोग कर सकते हैं लेकिन आपको इसे पहले से ही जानना होगा।पायथन में फ़ाइल के एन्कोडिंग को कैसे जानें?

import codecs 
f = codecs.open("file.txt", "r", "utf-8") 

क्या फ़ाइल का उपयोग करने के लिए स्वचालित रूप से एन्कोडिंग का उपयोग करने का कोई तरीका है?

अग्रिम धन्यवाद

संपादित करें: धन्यवाद बहुत ही दिलचस्प answsers के लिए हर कोई। तुम भी http://whatismyencoding.com/ जो chardet पर आधारित है द्वारा रुचि हो सकती है (साइट पर अधिक बोतल अजगर ढांचे द्वारा संचालित है)

उत्तर

19

दुर्भाग्यवश फ़ाइल को देखकर फ़ाइल के एन्कोडिंग को निर्धारित करने के लिए कोई 'सही' तरीका नहीं है। यह एक सार्वभौमिक समस्या है, जो कि अजगर या किसी विशेष फ़ाइल सिस्टम तक सीमित नहीं है।

यदि आप एक XML फ़ाइल पढ़ रहे हैं, तो फ़ाइल फ़ाइल में पहली पंक्ति आपको एन्कोडिंग का संकेत दे सकती है।

अन्यथा, आपको chardet (अन्य उत्तरों में दिए गए समाधानों में से एक) जैसे कुछ हेरिस्टिक्स-आधारित दृष्टिकोण का उपयोग करना होगा जो कच्चे बाइट प्रारूप में फ़ाइल में डेटा की जांच करके एन्कोडिंग अनुमान लगाने का प्रयास करता है। यदि आप विंडोज़ पर हैं, तो मेरा मानना ​​है कि विंडोज एपीआई फ़ाइल में डेटा के आधार पर एन्कोडिंग को आजमाने और अनुमान लगाने के तरीकों का खुलासा करता है।

3

Unicode DammitBeautiful Soup से है, जो chardet का उपयोग करता है लेकिन कुछ अतिरिक्त सुविधाएं जोड़ता है।

यह एक्सएमएल या एचटीएमएल फाइलों के अंदर से एन्कोडिंग पढ़ने की कोशिश करता है। फिर यह फ़ाइल की शुरुआत में बीओएम या ऐसा कुछ ढूंढने की कोशिश करता है। यदि यह ऐसा नहीं कर सकता है, तो यह chardet का उपयोग करता है।

3

एन्कोडिंग अनुमान लगाने में आपकी सहायता के लिए यहां एक छोटा सा स्निपेट है। यह लैटिन 1 और यूटीएफ 8 के बीच काफी अच्छा लगता है। यह एक बाइट स्ट्रिंग को एक यूनिकोड स्ट्रिंग में परिवर्तित करता है।

# Attention: Order of encoding_guess_list is import. Example: "latin1" always succeeds. 
encoding_guess_list=['utf8', 'latin1'] 
def try_unicode(string, errors='strict'): 
    if isinstance(string, unicode): 
     return string 
    assert isinstance(string, str), repr(string) 
    for enc in encoding_guess_list: 
     try: 
      return string.decode(enc, errors) 
     except UnicodeError, exc: 
      continue 
    raise UnicodeError('Failed to convert %r' % string) 
def test_try_unicode(): 
    for start, should in [ 
     ('\xfc', u'ü'), 
     ('\xc3\xbc', u'ü'), 
     ('\xbb', u'\xbb'), # postgres/psycopg2 latin1: RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 
     ]: 
     result=try_unicode(start, errors='strict') 
     if not result==should: 
      raise Exception(u'Error: start=%r should=%r result=%r' % (
        start, should, result)) 
+0

बहुत अच्छा विचार है। धन्यवाद। –

+0

मैंने इसे थोड़ा सा सरल बनाया और अनुकूलित किया, केवल एक .decode() को एक कोशिश में छोड़कर - जो कि (1) सफल रूपांतरण, या (2) encoding_guess_list को समाप्त करने के बाद टूट जाता है। अगर अंत असफल रहा, तो मैं 'सख्त' के बजाय 'प्रतिस्थापन' पर सेट त्रुटियों के साथ एक अलग .decode() लागू करता हूं। – JDM

1
#!/usr/bin/python 

""" 
Line by line detecting encoding if input and then convert it into UTF-8 
Suitable for look at logs with mixed encoding (i.e. from mail systems) 

""" 

import sys 
import chardet 

while 1: 
     l = sys.stdin.readline() 
     e = chardet.detect(l) 

     u = None 
     try: 
       if e['confidence'] > 0.3: 
         u = unicode(l, e['encoding']) 
     except: 
       pass 

     if u: 
       print u, 
     else: 
       print l, 
संबंधित मुद्दे