पायथन स्ट्रिंग में HTML संस्थाओं को डिकोड करें?


266

मैं सुंदर सूप 3 के साथ कुछ HTML पार्स कर रहा हूं, लेकिन इसमें HTML इकाइयां शामिल हैं जो सुंदर सूप 3 स्वचालित रूप से मेरे लिए डिकोड नहीं करता है:

>>> from BeautifulSoup import BeautifulSoup

>>> soup = BeautifulSoup("<p>&pound;682m</p>")
>>> text = soup.find("p").string

>>> print text
&pound;682m

मैं इसके बजाय textपाने के लिए HTML संस्थाओं को कैसे डीकोड कर सकता हूं ।"£682m""&pound;682m"


जवाबों:


521

पायथन 3.4+

उपयोग करें html.unescape():

import html
print(html.unescape('&pound;682m'))

FYI html.parser.HTMLParser.unescapeको हटा दिया जाता है , और इसे 3.5 में हटाया जाना चाहिए था , हालांकि इसे गलती से छोड़ दिया गया था। इसे जल्द ही भाषा से हटा दिया जाएगा।


पायथन 2.6-3.3

आप HTMLParser.unescape()मानक पुस्तकालय से उपयोग कर सकते हैं :

  • पायथन 2.6-2.7 के लिए यह अंदर है HTMLParser
  • पायथन 3 के लिए यह अंदर है html.parser
>>> try:
...     # Python 2.6-2.7 
...     from HTMLParser import HTMLParser
... except ImportError:
...     # Python 3
...     from html.parser import HTMLParser
... 
>>> h = HTMLParser()
>>> print(h.unescape('&pound;682m'))
£682m

sixआयात को आसान बनाने के लिए आप संगतता लाइब्रेरी का उपयोग कर सकते हैं :

>>> from six.moves.html_parser import HTMLParser
>>> h = HTMLParser()
>>> print(h.unescape('&pound;682m'))
£682m

9
यह विधि "& # 8217;" google app इंजन पर, हालांकि यह स्थानीय रूप से python2.6 पर काम करता है। यह अभी भी संस्थाओं (जैसे & quot;) को कम से कम करता है
gfxmonk

एक अनिर्दिष्ट एपीआई को कैसे हटाया जा सकता है? उत्तर को संपादित किया।
मार्कस यूटरवित्जर

@MarkusUnterwaditzer का कोई कारण नहीं है कि एक अनिर्दिष्ट विधि को पदावनत नहीं किया जा सकता है। यह एक डेप्रिसिएशन चेतावनी फेंकता है - उत्तर के लिए मेरा संपादन देखें।
मार्क एमी

यह अधिक तार्किक प्रतीत होगा कि, केवल unescapeविधि के बजाय , पूरे HTMLParserमॉड्यूल के पक्ष में पदावनत किया गया html.parser
टॉम रसेल

पायथन 2 के लिए वर्थ नोटिंग: विशेष वर्णों को उनके लैटिन -1 (ISO-8859-1) एन्कोडिंग समकक्षों के साथ बदल दिया जाता है। जैसे, यह आवश्यक हो सकता है h.unescape(s).encode("utf-8")। डॉक्स: "" "यहां दी गई परिभाषा में XHTML 1.0 द्वारा परिभाषित सभी इकाइयां शामिल हैं जिन्हें लैटिन -1 वर्ण सेट (ISO-8859-1)" "में सरल पाठात्मक प्रतिस्थापन का उपयोग करके संभाला जा सकता है"
गुमनाम कायर

65

सुंदर सूप इकाई रूपांतरण को संभालता है। सुंदर सूप 3 में, आपको कंस्ट्रक्टर convertEntitiesको तर्क निर्दिष्ट करना होगा BeautifulSoup( संग्रहित डॉक्स का 'इकाई रूपांतरण' अनुभाग देखें)। सुंदर सूप 4 में, इकाइयां अपने आप डिकोड हो जाती हैं।

सुंदर सूप ३

>>> from BeautifulSoup import BeautifulSoup
>>> BeautifulSoup("<p>&pound;682m</p>", 
...               convertEntities=BeautifulSoup.HTML_ENTITIES)
<p682m</p>

सुंदर सूप ४

>>> from bs4 import BeautifulSoup
>>> BeautifulSoup("<p>&pound;682m</p>")
<html><body><p682m</p></body></html>

+1। पता नहीं कैसे मैं इसे डॉक्स में याद किया: जानकारी के लिए धन्यवाद। मैं आकर्षक उत्तर को स्वीकार करने जा रहा हूं क्योंकि उसका मानक मानदंड का उपयोग करता है जिसे मैंने प्रश्न में निर्दिष्ट किया है (मेरे लिए महत्वपूर्ण नहीं) और अन्य लोगों के लिए इसका अधिक सामान्य उपयोग।
जेकेपी

5
BeautifulSoup4का उपयोग करता है HTMLParser, ज्यादातर। स्रोत
scharfmn

4
हम सभी विलुप्त HTML के बिना सुंदर सूप 4 में रूपांतरण कैसे प्राप्त करते हैं जो मूल स्ट्रिंग का हिस्सा नहीं था? (यानी <html> और <शरीर>)
प्रैक्सिटेलस

@Praxiteles: BeautifulSoup ('& £; 682m', "html.parser") stackoverflow.com/a/14822344/4376342
Soitje

13

आप w3lib.html लाइब्रेरी से रिप्लेसमेंट_एंटिस का उपयोग कर सकते हैं

In [202]: from w3lib.html import replace_entities

In [203]: replace_entities("&pound;682m")
Out[203]: u'\xa3682m'

In [204]: print replace_entities("&pound;682m")
£682m

2

सुंदर सूप 4 आपको अपने आउटपुट के लिए एक फॉर्मेटर सेट करने की अनुमति देता है

यदि आप पास होते हैं formatter=None, तो सुंदर सूप आउटपुट पर स्ट्रिंग्स को बिल्कुल भी संशोधित नहीं करेगा। यह सबसे तेज़ विकल्प है, लेकिन इससे इन उदाहरणों के अनुसार, अमान्य HTML / XML उत्पन्न करने वाले सुंदर सूप बन सकते हैं:

print(soup.prettify(formatter=None))
# <html>
#  <body>
#   <p>
#    Il a dit <<Sacré bleu!>>
#   </p>
#  </body>
# </html>

link_soup = BeautifulSoup('<a href="http://example.com/?foo=val1&bar=val2">A link</a>')
print(link_soup.a.encode(formatter=None))
# <a href="http://example.com/?foo=val1&bar=val2">A link</a>

इस सवाल का जवाब नहीं है। (इसके अलावा, मुझे पता नहीं है कि डॉक्स जो कह रहे हैं वह HTML के अंतिम बिट के बारे में अमान्य है।)
मार्क अमेरी

<< Sacré blu! >> यह अमान्य हिस्सा है, क्योंकि यह <और> से अलग हो गया है और इसके चारों ओर HTML टूट जाएगा। मुझे पता है कि यह मेरे लिए एक देर से पोस्ट है, लेकिन मामले में किसी को भी हो रहा है और आश्चर्य हो रहा है ...
GMasucci

0

मेरे पास एक समान एन्कोडिंग मुद्दा था। मैंने सामान्यीकरण () विधि का उपयोग किया। मेरे डेटा फ़्रेम को किसी अन्य निर्देशिका में .html फ़ाइल में निर्यात करते समय मुझे पंडों .to_html () पद्धति का उपयोग करके एक यूनिकोड त्रुटि मिल रही थी। मैं यह कर रहा हूँ और यह काम किया ...

    import unicodedata 

डेटाफ्रेम ऑब्जेक्ट आप की तरह हो सकता है, चलो इसे टेबल कहते हैं ...

    table = pd.DataFrame(data,columns=['Name','Team','OVR / POT'])
    table.index+= 1

टेबल डेटा को एनकोड करें ताकि हम इसे बाहर कर सकें।। html फ़ाइल को टेम्प्लेट फ़ोल्डर में (यह आपकी इच्छानुसार कोई भी स्थान हो सकता है :))

     #this is where the magic happens
     html_data=unicodedata.normalize('NFKD',table.to_html()).encode('ascii','ignore')

html फ़ाइल में सामान्यीकृत स्ट्रिंग निर्यात करें

    file = open("templates/home.html","w") 

    file.write(html_data) 

    file.close() 

संदर्भ: यूनिकोडेटा प्रलेखन


-4

यह शायद यहाँ प्रासंगिक नहीं है। लेकिन इन html को खत्म करने के लिए एक पूरे दस्तावेज़ से प्रवेश किया जाता है, आप कुछ इस तरह से कर सकते हैं: (दस्तावेज = पृष्ठ मान लें और कृपया मैला कोड को माफ कर दें, लेकिन अगर आपके पास यह विचार है कि इसे और बेहतर कैसे बनाया जाए, तो सभी कानों में - Im new to) यह)।

import re
import HTMLParser

regexp = "&.+?;" 
list_of_html = re.findall(regexp, page) #finds all html entites in page
for e in list_of_html:
    h = HTMLParser.HTMLParser()
    unescaped = h.unescape(e) #finds the unescaped value of the html entity
    page = page.replace(e, unescaped) #replaces html entity with unescaped value

7
नहीं! आपको अपने आप से HTML संस्थाओं का मिलान करने और उन पर लूप करने की आवश्यकता नहीं है; .unescape()करता है कि आप के लिए । मुझे समझ में नहीं आ रहा है कि आपने और रोब ने इन अतिव्यापी समाधानों को क्यों पोस्ट किया है जो अपनी स्वयं की इकाई को रोल करते हैं जब स्वीकृत उत्तर पहले से ही स्पष्ट रूप से दिखाता है कि .unescape()स्ट्रिंग में इकाइयां मिल सकती हैं।
मार्क ऐमी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.