2018 अपडेट:
फरवरी 2018 तक, जैसे कंप्रेशन्स का उपयोग करना काफी लोकप्रियgzip
हो गया है (सभी वेबसाइटों के लगभग 73% लोग इसका उपयोग करते हैं, जिसमें Google, YouTube, Yahoo, Wikipedia, Reddit, Stack Overflow और Stack Exchange Network sites जैसी बड़ी साइटें शामिल हैं)।
यदि आप एक सरल डिकोड करते हैं जैसे कि मूल उत्तर में gzipped प्रतिक्रिया के साथ, तो आपको इस तरह की या इसके जैसी त्रुटि मिलेगी:
यूनिकोडडॉफॉर्सेट: 'utf8' कोडक 0x8b को बाइट नहीं कर सकता है 1 स्थिति में: अप्रत्याशित कोड बाइट
एक gzpipped प्रतिक्रिया को डीकोड करने के लिए आपको निम्नलिखित मॉड्यूल (पायथन 3 में) जोड़ने की आवश्यकता है:
import gzip
import io
नोट: अजगर 2 में आप StringIO
इसके बजाय का उपयोग करेंगेio
तब आप इस तरह से सामग्री को पार्स कर सकते हैं:
response = urlopen("https://example.com/gzipped-ressource")
buffer = io.BytesIO(response.read()) # Use StringIO.StringIO(response.read()) in Python 2
gzipped_file = gzip.GzipFile(fileobj=buffer)
decoded = gzipped_file.read()
content = decoded.decode("utf-8") # Replace utf-8 with the source encoding of your requested resource
यह कोड प्रतिक्रिया को पढ़ता है, और बाइट्स को बफर में रखता है। gzip
मॉड्यूल तो बफर का उपयोग कर पढ़ता GZipFile
कार्य करते हैं। उसके बाद, gzipped फ़ाइल को फिर से बाइट्स में पढ़ा जा सकता है और अंत में सामान्य रूप से पठनीय पाठ को डिकोड किया जा सकता है।
मूल उत्तर 2010 से:
क्या हम वास्तविक मूल्य का उपयोग कर सकते हैं link
?
इसके अलावा, हम आमतौर पर इस समस्या का सामना तब करते हैं जब हम .encode()
पहले से ही एन्कोडेड बाइट स्ट्रिंग की कोशिश कर रहे होते हैं । तो आप इसे पहले के रूप में डीकोड करने का प्रयास कर सकते हैं
html = urllib.urlopen(link).read()
unicode_str = html.decode(<source encoding>)
encoded_str = unicode_str.encode("utf8")
उदहारण के लिए:
html = '\xa0'
encoded_str = html.encode("utf8")
के साथ विफल हो जाता है
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)
जबकि:
html = '\xa0'
decoded_str = html.decode("windows-1252")
encoded_str = decoded_str.encode("utf8")
त्रुटि के बिना सफलता। ध्यान दें कि "विंडोज़ -1252" एक ऐसी चीज है जिसका मैंने एक उदाहरण के रूप में उपयोग किया है । मुझे यह चारडेट से मिला और इसमें 0.5 विश्वास था कि यह सही है! (ठीक है, जैसा कि 1-चरित्र-लंबाई स्ट्रिंग के साथ दिया गया है, आप क्या उम्मीद करते हैं) आपको यह बदलना चाहिए कि .urlopen().read()
जो सामग्री आपने प्राप्त की थी, उस पर लागू होने वाली बाइट स्ट्रिंग के एन्कोडिंग पर वापस आ जाएगी ।
मेरी एक और समस्या यह है कि .encode()
स्ट्रिंग विधि संशोधित स्ट्रिंग लौटाती है और स्रोत को संशोधित नहीं करती है। तो यह बेकार की तरह है self.response.out.write(html)
क्योंकि html html.encode से एन्कोडेड स्ट्रिंग नहीं है (यदि ऐसा है तो आप मूल रूप से लक्ष्य कर रहे थे)।
जैसा कि इग्नासियो ने सुझाव दिया था, लौटे स्ट्रिंग के वास्तविक एन्कोडिंग के लिए स्रोत वेबपेज की जाँच करें read()
। यह या तो मेटा टैग्स में से एक है या प्रतिक्रिया में ContentType हेडर में। उसके बाद के पैरामीटर के रूप में इसका उपयोग करें .decode()
।
हालांकि ध्यान दें कि यह नहीं माना जाना चाहिए कि हेडर और / या मेटा चरित्र सेट घोषणाओं को वास्तविक सामग्री से मेल खाने के लिए अन्य डेवलपर्स पर्याप्त जिम्मेदार हैं। (जो एक पीआईटीए है, हाँ, मुझे पता होना चाहिए, मैं उनमें से एक था )।