2010-12-22 10 views
12

मुझे आश्चर्य है कि पाइथन के साथ एक वेबपृष्ठ का एक अक्षर प्राप्त करना बहुत जटिल है। क्या मुझे कोई रास्ता याद आ रहा है? HTTPMessage में बहुत सारे फ़ंक्शन हैं, लेकिन यह नहीं।वेबपृष्ठ के अक्षर प्राप्त करने के लिए एक अच्छा, विश्वसनीय लघु तरीका क्या है?

>>> google = urllib2.urlopen('http://www.google.com/') 
>>> google.headers.gettype() 
'text/html' 
>>> google.headers.getencoding() 
'7bit' 
>>> google.headers.getcharset() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: HTTPMessage instance has no attribute 'getcharset' 

तो आपको हेडर प्राप्त करना होगा, और इसे विभाजित करना होगा। दो बार।

>>> google = urllib2.urlopen('http://www.google.com/') 
>>> charset = 'ISO-8859-1' 
>>> contenttype = google.headers.getheader('Content-Type', '') 
>>> if ';' in contenttype: 
...  charset = contenttype.split(';')[1].split('=')[1] 
>>> charset 
'ISO-8859-1' 

यह एक बुनियादी कार्य के लिए आश्चर्यजनक मात्रा में कदम है। क्या मैं कुछ भूल रहा हूँ?

+2

2616 (HTTP1.1) ' डेटा के चरित्र सेट (सेक्शन 3.4) को परिभाषित करने के लिए "मीडियासेट" पैरामीटर का उपयोग कुछ मीडिया प्रकारों के साथ किया जाता है। जब प्रेषक द्वारा कोई स्पष्ट वर्णमाला पैरामीटर प्रदान नहीं किया जाता है, तो "टेक्स्ट" प्रकार के मीडिया उपप्रकारों को HTTP के माध्यम से प्राप्त होने पर "आईएसओ -885 9 -1" के डिफ़ॉल्ट वर्णसेट मान के रूप में परिभाषित किया जाता है, जो आपके डिफ़ॉल्ट पर साइड-नोट के रूप में होता है ASCII होने के नाते। – plundra

+0

@plundra: ठीक है, आईएसओ -885 9 -1 एएससीआईआई का एक सुपरसेट है, लेकिन आप सही हैं - यह एक अलग एन्कोडिंग है। – Piskvor

+0

@Piskvor: और यदि कोई ऊपर से 'charset' का उपयोग करना था।उदाहरण के लिए, डीकोड() चीजें तोड़ जाएंगी (आईएसओ -885 9 -1 भेजने वाले पृष्ठों के साथ और अंतर्निहित पर निर्भर करता है) – plundra

उत्तर

6

क्या आपने इसे चेक किया है?

How to download any(!) webpage with correct charset in python?

+0

नहीं, मैंने नहीं किया था। धन्यवाद! –

+2

तो मुझे कुछ याद आया था, अर्थात् '.headers.getparam ('charset') ', जो बहुत सरल बनाता है। –

0

तुम कुछ भी याद आ रही नहीं कर रहे हैं। यह सही काम कर रहा है - एक HTTP प्रतिक्रिया का एन्कोडिंग सामग्री-प्रकार का एक उप-भाग है।

ध्यान दें कि कुछ पेज केवल Content-Type: text/html भेज सकते हैं और फिर <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> के माध्यम से एन्कोडिंग सेट कर सकते हैं - यह एक बदसूरत हैक हालांकि (पृष्ठ लेखक के हिस्से पर) है और यह बहुत आम नहीं है।

0

मैं chardet यूनिवर्सल एन्कोडिंग डिटेक्टर के साथ जाऊंगा।

>>> import urllib 
>>> urlread = lambda url: urllib.urlopen(url).read() 
>>> import chardet 
>>> chardet.detect(urlread("http://google.cn/")) 
{'encoding': 'GB2312', 'confidence': 0.99} 

आप सही कर रहे हैं, लेकिन अपने दृष्टिकोण जिन पन्नों पर चारसेट meta टैग पर घोषित किया जाता है या बिल्कुल भी घोषित नहीं किया गया है के लिए विफल हो जाएगा।
यदि आप चार्टेट स्रोतों के करीब देखते हैं, तो इसमें charsetprober/charsetgroupprober मॉड्यूल हैं जो इस समस्या से अच्छी तरह से संबंधित हैं।

+0

मेरे लिए, यह एक अच्छा जवाब नहीं है: chardet "[HTML] फ़ाइल के एन्कोडिंग का अनुमान लगा रहा है" (https://github.com/erikrose/chardet देखें)। अगर आपको घोषित किया जाता है तो आपको हेडर को देखकर पहली बार शुरू करना चाहिए। लेनिल द्वारा निर्देशित प्रश्न देखें। – lajarre

3

मैं कुछ शोध किया और इस समाधान के साथ आया था:

response = urllib.request.urlopen(url) 
encoding = response.headers.get_content_charset() 

यह मैं कैसे पायथन 3. में ऐसा होता है मैं अजगर 2 में यह परीक्षण नहीं किया है, लेकिन मैं अनुमान लगा रहा हूँ आप के लिए होता है कि urllib.request के बजाय urllib2.request का उपयोग करने के लिए।

यहां यह काम करता है कि यह कैसे काम करता है, क्योंकि आधिकारिक पायथन दस्तावेज़ इसे बहुत अच्छी तरह से समझाता नहीं है: urlopen का परिणाम http.client.HTTPResponse ऑब्जेक्ट है। headers इस ऑब्जेक्ट की प्रॉपर्टी http.client.HTTPMessage ऑब्जेक्ट है, जो प्रलेखन के अनुसार, "email.message.Message क्लास का उपयोग करके कार्यान्वित किया गया है", जिसमें get_content_charset नामक एक विधि है, जो प्रतिक्रिया के चरित्र सेट को निर्धारित करने और वापस करने का प्रयास करती है।

डिफ़ॉल्ट रूप से, इस विधि देता है None अगर यह वर्ण सेट निर्धारित करने में असमर्थ है, लेकिन आप एक failobj पैरामीटर पारित करके इसके स्थान पर इस व्यवहार को ओवरराइड कर सकते हैं:

encoding = response.headers.get_content_charset(failobj="utf-8") 
आरएफसी से
+0

'get_content_charset' पायथन 2 में उपलब्ध नहीं है। आप' headers.getparam ("charset") 'के बजाय' पाइथन 2 का उपयोग करने में सक्षम होना चाहिए; पायथन 3 इसे 'get_param'' नाम देता है। –

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

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