समस्या है कि यहाँ, के रूप में ऑस्टिन फिलिप्स, urllib2.Request
के निर्माता के data
पैरामीटर ने बताया है:
एक स्ट्रिंग अतिरिक्त डेटा को निर्दिष्ट सर्वर से भेजने के लिए हो सकता है ... data
मानक में एक बफर होना चाहिए एप्लिकेशन/एक्स-www-form-urlencoded प्रारूप। Urllib.urlencode() फ़ंक्शन 2-टुपल्स का मैपिंग या अनुक्रम लेता है और इस प्रारूप में एक स्ट्रिंग देता है।
इसे urlencoded डेटा के बजाय JSON-encoded डेटा पास करके, आप इसे कहीं भ्रमित कर रहे हैं।
आंकड़ों के अनुरोध डेटा सेट करें:
हालांकि, Request
एक विधि add_data
है। इसे HTTP हैंडलर को छोड़कर सभी हैंडलर द्वारा अनदेखा किया जाता है - और वहां यह एक बाइट स्ट्रिंग होना चाहिए, और जीईटी के बजाय अनुरोध पोस्ट को बदल देगा।
आप इस का उपयोग करते हैं, तो आप शायद भी add_header
बल्कि निर्माता में इसे पारित से इस्तेमाल करना चाहिए, हालांकि यह है कि विशेष रूप से दस्तावेज में कहीं भी उल्लेख किया जाना प्रतीत नहीं होता।
तो, यह काम करना चाहिए:
req = urllib2.Request(url)
req.add_data("{'some':'data'}")
req.add_header('Content-Type', 'application/json; charset=utf-8')
res = urllib2.urlopen(req)
एक टिप्पणी में, आप ने कहा:
कारण बाहर क्यों खोजने के बिना मैं सिर्फ अनुरोध पर स्विच नहीं करना चाहते मैं यह समस्या देख रहा हूं कि कुछ गहरा अंतर्निहित मुद्दा हो सकता है कि यह इंगित करता है कि बाद में वापस आ सकता है और बाद में समस्याओं का पता लगाना मुश्किल हो सकता है।
यदि आप गहरे अंतर्निहित मुद्दों को ढूंढना चाहते हैं, तो आप केवल अपने क्लाइंट-साइड स्रोत को देखकर ऐसा नहीं करेंगे। "एक्स काम क्यों करता है लेकिन वाई विफल रहता है" को समझने का पहला कदम? नेटवर्क कोड के साथ यह पता लगाने के लिए कि बाइट एक्स और वाई प्रत्येक भेजता है। फिर आप प्रासंगिक अंतर को कम करने की कोशिश कर सकते हैं, और उसके बाद पता लगाएं कि आपके कोड का कौन सा हिस्सा वाई को प्रासंगिक स्थान पर गलत डेटा भेजने के कारण है।
आप सेवा पर चीजों को लॉग इन करके (यदि आप इसे नियंत्रित करते हैं), Wireshark चलाना आदि कर सकते हैं, लेकिन सरल मामलों के लिए सबसे आसान तरीका नेटकैट है। आपको अपने सिस्टम के लिए man nc
पढ़ने की आवश्यकता होगी (और, विंडोज़ पर, आपको इसे चलाने से पहले नेटकैट प्राप्त करने और इंस्टॉल करने की आवश्यकता होगी), क्योंकि प्रत्येक संस्करण के लिए वाक्यविन्यास अलग है, लेकिन यह हमेशा nc -kl 12345
जैसा कुछ आसान है।
फिर, अपने ग्राहक में, होस्ट नाम के स्थान पर localhost:12345
का उपयोग करने के लिए यूआरएल बदलें, और यह नेटकैट से जुड़ जाएगा और इसके HTTP अनुरोध को भेज देगा, जिसे टर्मिनल पर डाला जाएगा। इसके बाद आप इसे कॉपी कर सकते हैं और nc HOST 80
का उपयोग कर सकते हैं और यह देखने के लिए पेस्ट कर सकते हैं कि वास्तविक सर्वर कैसे प्रतिक्रिया देता है, और उस समस्या को कम करने के लिए इसका उपयोग करें। या, यदि आप अटक जाते हैं, तो कम से कम आप डेटा को अपने SO प्रश्न पर कॉपी और पेस्ट कर सकते हैं।
एक आखिरी बात: यह लगभग निश्चित रूप से आपकी समस्या से संबंधित नहीं है (क्योंकि आप requests
साथ ठीक उसी डेटा भेज रहे हैं और यह काम कर रहा है), लेकिन अपने डेटा वास्तव में मान्य JSON, क्योंकि यह एक का उपयोग करता है नहीं है डबल उद्धरण के बजाय उद्धरण। the docs के अनुसार, string
के रूप में परिभाषित किया गया है:
string
""
" chars "
, वास्तव में साधारण परीक्षण मामलों को छोड़कर (। डॉक्स एक अच्छा चित्रमय प्रतिनिधित्व के रूप में अच्छी तरह से है)
सामान्य तौर पर, आप JSON लिखने के लिए नहीं करना चाहते हैं हाथ से। कई मामलों में (आपके सहित), आपको केवल "…"
json.dumps(…)
के साथ प्रतिस्थापित करना है, इसलिए यह गंभीर कठिनाई नहीं है। तो:
req = urllib2.Request(url)
req.add_data(json.dumps({'some':'data'}))
req.add_header('Content-Type', 'application/json; charset=utf-8')
res = urllib2.urlopen(req)
तो, यह क्यों काम कर रहा है? खैर, जावास्क्रिप्ट में, एकल-उद्धृत तार कानूनी हैं, साथ ही बैकस्लैश जैसी अन्य चीजें जेएसओएन में मान्य नहीं हैं, और किसी भी जेएस कोड जो पार्सिंग के लिए प्रतिबंधित-eval (या, बदतर, कच्चे eval) का उपयोग करता है उसे स्वीकार करेगा । और, क्योंकि इस वजह से बहुत से लोगों को खराब JSON लिखने के लिए उपयोग किया जाता है, इसलिए कई ब्राउज़रों के मूल JSON पार्सर्स और अन्य भाषाओं में कई JSON पुस्तकालयों में सामान्य त्रुटियों की अनुमति देने के लिए कामकाज होते हैं। लेकिन आपको उस पर भरोसा नहीं करना चाहिए।
यदि आप दोनों द्वारा भेजे गए शीर्षकों की तुलना करते हैं, तो वे समान नहीं होंगे। (उदाहरण के लिए, 'अनुरोध 'को' स्वीकृति-एन्कोडिंग: gzip, deflate, compress' 'पर' डिफ़ॉल्ट 'को' एसीप्ट-एन्कोडिंग: पहचान' 'के दौरान डिफ़ॉल्ट रूप से डिफ़ॉल्ट रूप से परिभाषित किया जाता है।) प्रत्येक संस्करण के साथ अनुरोध शीर्षलेखों को कैप्चर करें, और सर्वर का उपयोग करके उन्हें फिर से चलाएं , उदाहरण के लिए, 'एनसी' और देखें कि यह कैसे प्रतिक्रिया करता है।या तो 'urllib2' हेडर के बारे में कुछ 502 त्रुटि उत्पन्न कर रहा है, या यह किसी प्रकार का रीडायरेक्ट/आदि कर रहा है। urllib2 द्वारा समझने वाले अनुरोध नहीं करते हैं। – abarnert
इसके अलावा ... अगर यह 'अनुरोध' के साथ काम करता है, तो क्या कोई कारण है कि आप केवल 'अनुरोध' का उपयोग नहीं कर सकते हैं? – abarnert
['urllib2.Request'] के लिए दस्तावेज़ (http://docs.python.org/2/library/urllib2.html#urllib2.Request) इंगित करता है कि * डेटा * पैरामीटर को urlencoded * अनुप्रयोग/x- www फार्म-urlencoded *। –