2010-06-27 24 views
21

मैं यह समझने की कोशिश करने में बहुत थक गया हूं कि यह कोड पाइथन 2 में क्यों काम करता है और पायथन 3 में नहीं। मैं बस जेसन का एक पृष्ठ पकड़ने की कोशिश कर रहा हूं और फिर पार्स यह।पायथन 2 बनाम पायथन 3 - urllib प्रारूप

import urllib, json 
response = urllib.urlopen("http://reddit.com/.json") 
content = response.read() 
data = json.loads(content) 

मैं सोचा अजगर 3 में बराबर कोड इस होगा:: यहाँ अजगर 2 में कोड है

import urllib.request, json 
response = urllib.request.urlopen("http://reddit.com/.json") 
content = response.read() 
data = json.loads(content) 

लेकिन यह, मेरे चेहरे में चल रही है क्योंकि डेटा पढ़ने द्वारा दिया () एक "बाइट्स" प्रकार है। हालांकि, मैं अपने जीवन के लिए ऐसा कुछ नहीं कर सकता जो कि जेसन पार्स करने में सक्षम हो। मैं हेडर कि reddit utf-8 मेरे पास वापस भेजने की कोशिश कर रहा है से पता है, लेकिन मैं बाइट्स utf-8 में डिकोड करने के लिए प्राप्त करने के लिए प्रतीत नहीं कर सकते हैं:

import urllib.request, json 
response = urllib.request.urlopen("http://reddit.com/.json") 
content = response.read() 
data = json.loads(content.decode("utf8")) 

क्या मैं गलत कर रहा हूँ?

संपादित करें: समस्या यह है कि मैं डेटा को उपयोग करने योग्य स्थिति में नहीं प्राप्त कर सकता; भले ही जेसन डेटा लोड करता है, इसका हिस्सा अवांछित है, और मैं स्क्रीन पर डेटा प्रिंट करने में सक्षम होना चाहता हूं।

दूसरा संपादन: समस्या को पार्सिंग की तुलना में प्रिंट के साथ और अधिक करना है, ऐसा लगता है। एलेक्स का जवाब आईओएफ को आईटीएफ 8 पर सेट करके, स्क्रिप्ट के लिए पाइथन 3 में काम करने का एक तरीका प्रदान करता है। लेकिन एक सवाल अभी भी बना हुआ है: कोड यह है कि कोड पायथन 2 में क्यों काम करता है, लेकिन पायथन 3 नहीं?

उत्तर

15

आपके द्वारा पोस्ट किया गया कोड संभावित रूप से गलत कट-एंड-पेस्ट ऑपरेशंस के कारण है क्योंकि यह दोनों संस्करणों में स्पष्ट रूप से गलत है (f.read() विफल रहता है क्योंकि f बैरनेम परिभाषित नहीं है)।

पी 3, ur = response.decode('utf8') में मेरे लिए पूरी तरह से अच्छा काम करता है, जैसा कि निम्नलिखित json.loads(ur) करता है। हो सकता है कि गलत copys-and-pastes ने आपके 2-से-3 रूपांतरण प्रयासों को प्रभावित किया।

+0

ओह, मैं कोड गलतियों को ठीक कर दूंगा ... मैंने इसे प्रदर्शन के लिए सुधारने की कोशिश की लेकिन प्रक्रिया में इसे सबकुछ खराब कर दिया। : पी भले ही, मैं इसे पार्स करने के बाद डेटा को नहीं देख सकता (एक साधारण "प्रिंट (डेटा)" का उपयोग करके) क्योंकि यह मुझे आकर्षक त्रुटियां देता है। –

+0

@ डैनियल, समस्याएं _after_ आपको डेटा प्राप्त करने के बारे में डेटा से प्राप्त एक अलग सवाल प्रतीत होता है (जो मेरा जवाब, ऐसा प्रतीत होता है, जवाब दिया - हालांकि प्रतीत होता है कि आप सहमत नहीं हैं, क्योंकि आपने नहीं किया है ' टी भी इसे ऊपर उठाओ!)। यदि 'डेटा' से आपका मतलब है 'json.loads (प्रतिक्रिया)', तो मैं बिना किसी समस्या के इसे प्रिंट कर सकता हूं (मेरे मैक टर्मिनल.एप पर, जो यूटीएफ -8 का समर्थन करता है)। आपका sys.stdout.encoding क्या है? क्या आपने पाइथन 3 शुरू करने से पहले पर्यावरण चर 'PYTHONIOENCODING: एन्कोडिंग [: त्रुटियों] stdin/stdout/stderr' के लिए ठीक से सेट किया है? आदि, आदि - पूरी तरह से अलग मुद्दों, देखें। –

+0

क्षमा करें अगर मैं पहले अस्पष्ट था। मूल समस्या यह है कि मैं * पार्सिंग के बाद डेटा का उपयोग नहीं कर सकता, किसी भी कारण से (प्रिंट केवल इसकी शुरुआत है; अगर मैं इसे प्रिंट नहीं कर सकता, तो लाइन के नीचे कहीं भी मैं परेशानी में भागने जा रहा हूं डेटा पढ़ना)। मैं एन्कोडिंग की जांच करूंगा, यह कहने के लिए पर्याप्त है कि यह मेरी W7 मशीन पर काम नहीं करता है। –

0

कृपया that अन्य यूनिकोड से संबंधित प्रश्न में उत्तर दें।

अब: पायथन 3 str (जो पायथन 2 unicode था) प्रकार एक आदर्श वस्तु है, इस अर्थ में कि यह "वर्ण" से संबंधित है, न कि "बाइट्स"। इन वर्णों को डिस्क/नेटवर्क डेटा के लिए/उपयोग करने के लिए, "रूपांतरण तालिका", a.k.a एन्कोडिंग a.k.a codepage द्वारा बाइट्स से एन्कोडेड-इन/डीकोडेड होना आवश्यक है। ऑपरेटिंग सिस्टम किस्म की वजह से, पाइथन ने ऐतिहासिक रूप से यह अनुमान लगाने से परहेज किया कि वह एन्कोडिंग क्या होनी चाहिए; यह वर्षों से बदल रहा है, लेकिन अभी भी "अस्पष्टता के चेहरे में, अनुमान लगाने के लिए प्रलोभन से इनकार करते हैं" का सिद्धांत लागू होता है।

शुक्र है, एक वेब सर्वर आपके काम को आसान बनाता है। ऊपर अपने response आप की जरूरत सभी अतिरिक्त जानकारी देना चाहिए:

>>> response.headers['content-type'] 
'application/json; charset=UTF-8' 

तो, हर बार जब आप एक वेब सर्वर के लिए एक अनुरोध एक चारसेट मूल्य के लिए सामग्री प्रकार हेडर की जाँच जारी है, और यूनिकोड में अनुरोध के डेटा को डिकोड (पाइथन 3: bytes.decode(charset)str) उस वर्णमाला का उपयोग करके।

6

आपके पाइथन संस्करण पर निर्भर करता है कि आपको सही लाइब्रेरी चुननी है।

अजगर 3,5

import urllib.request 
data = urllib.request.urlopen(url).read().decode('utf8') 

अजगर 2 के लिए के लिए

।7

import urllib 
url = serviceurl + urllib.urlencode({'sensor':'false', 'address': address}) 
uh = urllib.urlopen(url) 
+0

आप अपने कोड को स्पष्ट करने के लिए एक स्पष्टीकरण प्रदान करना चाहते हैं। – GabrielOshiro