পাইথন / জ্যাঙ্গো ব্যবহার করে কীভাবে আমি HTML ডিকোডিং / এনকোডিং করব?


127

আমার কাছে একটি স্ট্রিং রয়েছে যা এইচটিএমএল এনকোডযুক্ত রয়েছে:

'''<img class="size-medium wp-image-113"\
 style="margin-left: 15px;" title="su1"\
 src="http://blah.org/wp-content/uploads/2008/10/su1-300x194.jpg"\
 alt="" width="300" height="194" />'''

আমি এটিতে পরিবর্তন করতে চাই:

<img class="size-medium wp-image-113" style="margin-left: 15px;" 
  title="su1" src="http://blah.org/wp-content/uploads/2008/10/su1-300x194.jpg" 
  alt="" width="300" height="194" /> 

আমি এটি এইচটিএমএল হিসাবে নিবন্ধিত করতে চাই যাতে এটি পাঠ্য হিসাবে প্রদর্শিত না হয়ে ব্রাউজার দ্বারা একটি চিত্র হিসাবে রেন্ডার করা হয়।

স্ট্রিংটি সেভাবে সংরক্ষণ করা হয় কারণ আমি একটি ওয়েব স্ক্র্যাপিং সরঞ্জামটি ব্যবহার করছি BeautifulSoup, এটি একটি ওয়েব পৃষ্ঠাকে "স্ক্যান" করে এবং এর থেকে নির্দিষ্ট সামগ্রী পেয়ে যায়, তারপরে স্ট্রিংটি সেই বিন্যাসে ফেরত দেয়।

এটি সি # তে কীভাবে করা যায় তা পাই কিন্তু পাইথনে নয় । কেউ আমাকে সাহায্য করতে পারেন?

সম্পর্কিত

উত্তর:


118

জ্যাঙ্গো ব্যবহারের ক্ষেত্রে দেওয়া, এর দুটি উত্তর রয়েছে। django.utils.html.escapeরেফারেন্সের জন্য এটি এখানে রয়েছে :

def escape(html):
    """Returns the given HTML with ampersands, quotes and carets encoded."""
    return mark_safe(force_unicode(html).replace('&', '&amp;').replace('<', '&l
t;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;'))

এটির বিপরীতে, জ্যাকের উত্তরে বর্ণিত চিতা ফাংশনটি কাজ করা উচিত, তবে একক উদ্ধৃতি অনুপস্থিত। এই ভার্সনে সাম্প্রতিক সমস্যা এড়াতে প্রতিস্থাপনের ক্রমটি বিপরীত সহ একটি আপডেটড টুপল অন্তর্ভুক্ত রয়েছে:

def html_decode(s):
    """
    Returns the ASCII decoded version of the given HTML string. This does
    NOT remove normal HTML tags like <p>.
    """
    htmlCodes = (
            ("'", '&#39;'),
            ('"', '&quot;'),
            ('>', '&gt;'),
            ('<', '&lt;'),
            ('&', '&amp;')
        )
    for code in htmlCodes:
        s = s.replace(code[1], code[0])
    return s

unescaped = html_decode(my_string)

এটি অবশ্য সাধারণ সমাধান নয়; এটি শুধুমাত্র এনকোডযুক্ত স্ট্রিংগুলির জন্য উপযুক্ত django.utils.html.escape। সাধারণভাবে, স্ট্যান্ডার্ড লাইব্রেরিটির সাথে থাকা ভাল ধারণা:

# Python 2.x:
import HTMLParser
html_parser = HTMLParser.HTMLParser()
unescaped = html_parser.unescape(my_string)

# Python 3.x:
import html.parser
html_parser = html.parser.HTMLParser()
unescaped = html_parser.unescape(my_string)

# >= Python 3.5:
from html import unescape
unescaped = unescape(my_string)

একটি পরামর্শ হিসাবে: এটি আপনার ডাটাবেসে অনস্কেপযুক্ত এইচটিএমএল সংরক্ষণ করা আরও বোধ করতে পারে। যদি সম্ভব হয় তবে বিউটিসোল্প থেকে অনাকাঙ্ক্ষিত ফলাফলগুলি ফিরে পাওয়া এবং পুরোপুরি এই প্রক্রিয়াটি এড়ানো উচিত নয়।

জ্যাঙ্গোর সাথে, কেবলমাত্র টেমপ্লেট রেন্ডারিংয়ের সময় পলায়ন ঘটে; যাতে পালানো রোধ করতে আপনি কেবল টেম্পলটিং ইঞ্জিনকে বলুন যে আপনার স্ট্রিংটি এড়ানোর জন্য নয়। এটি করতে, আপনার টেমপ্লেটে এই বিকল্পগুলির একটি ব্যবহার করুন:

{{ context_var|safe }}
{% autoescape off %}
    {{ context_var }}
{% endautoescape %}

1
জ্যাঙ্গো বা চিতা ব্যবহার করবেন না কেন?
মাদুর

4
Django.utils.html.escape এর কোনও বিপরীত নেই?
মাদুর

12
আমি মনে করি টেমপ্লেট রেন্ডারিংয়ের সময় কেবল জাজানোতে পালানো ঘটে। অতএব, আনস্কেসের প্রয়োজন নেই - আপনি কেবল উদ্দীপনা ইঞ্জিনকে এড়াতে বলুন। হয় {{প্রসঙ্গ_ভারা | নিরাপদ}} বা {% অটোরস্কেপ%%} {{প্রসঙ্গ_ভার}} end% এন্ডোটোসকেপ%}
ড্যানিয়েল

3
@ ড্যানিয়েল: দয়া করে আপনার মন্তব্যটিকে একটি উত্তরে পরিবর্তন করুন যাতে আমি এটিতে ভোট দিতে পারি! | আমি (এবং আমি নিশ্চিত অন্যরা) ঠিক এই প্রশ্নের উত্তরে যা খুঁজছিলাম সেফটি ছিল।
ওয়েইন কোয়ার্টস

1
html.parser.HTMLParser().unescape()3.5 এ অবমূল্যায়িত হয়েছে। html.unescape()পরিবর্তে ব্যবহার করুন।
pjvandehaar

114

স্ট্যান্ডার্ড লাইব্রেরি সহ:

  • এইচটিএমএল এস্কেপ

    try:
        from html import escape  # python 3.x
    except ImportError:
        from cgi import escape  # python 2.x
    
    print(escape("<"))
  • এইচটিএমএল ইউনেস্কেপ

    try:
        from html import unescape  # python 3.4+
    except ImportError:
        try:
            from html.parser import HTMLParser  # python 3.x (<3.4)
        except ImportError:
            from HTMLParser import HTMLParser  # python 2.x
        unescape = HTMLParser().unescape
    
    print(unescape("&gt;"))

12
আমি মনে করি এটি সবচেয়ে সোজা, 'ব্যাটারি অন্তর্ভুক্ত' এবং সঠিক উত্তর। আমি জানি না লোকেরা কেন সেই জ্যাঙ্গো / চিতা জিনিসকে ভোট দেয়।
ড্যানিয়েল বকতিয়ার

আমিও তাই মনে করি, এই উত্তরটি সম্পূর্ণ বলে মনে হচ্ছে না। HTMLParserসাবক্ল্যাস করা দরকার, যে কোনও বস্তুর খাওয়ানো হয় তার সমস্ত অংশের সাথে কী করা উচিত তা জানাতে হবে, এবং তারপরে এখানে দেখা যায়, বস্তুকে পার্স করার জন্য খাওয়ানো হয়েছে । এছাড়াও, আপনি এখনও name2codepointপ্রতিটি এইচটিএমএল পরিচয়টিকে উপস্থাপন করে এমন প্রকৃত চরে রূপান্তর করতে ডিক ব্যবহার করতে চাইবেন ।
মার্কনিয়াস

তুমি ঠিক বলছো. HTMLParserযদি আমরা এটিতে কোনও HTML সত্ত্বা রাখি তবে আমাদের ইচ্ছামত অসমর্থিতরা কাজ করতে পারে না। এটি লুকিয়ে রাখার htmlparserজন্য হয়তো আমার নতুন নামকরণ করা উচিত _htmlparser, এবং কেবল unescapeকোনও সহায়ক ফাংশনের মতোই পদ্ধতিটি প্রকাশ করা হয়েছে।
জিয়াং জাং

3
২০১৫ সালের জন্য একটি নোট, এইচটিএমএলপার্স.উনস্কেপ পাই ৩.৪ এ অবমানিত এবং 3.5 এ সরানো হয়েছে। from html import unescapeপরিবর্তে ব্যবহার করুন
করোলিস রাইসেলিস

2
নোট করুন যে এটি জার্মান উমলাউট ("Ü") এর মতো বিশেষ অক্ষরগুলি পরিচালনা করে না
576i

80

এইচটিএমএল এনকোডিংয়ের জন্য, স্ট্যান্ডার্ড লাইব্রেরি থেকে cgi.escape রয়েছে :

>> help(cgi.escape)
cgi.escape = escape(s, quote=None)
    Replace special characters "&", "<" and ">" to HTML-safe sequences.
    If the optional flag quote is true, the quotation mark character (")
    is also translated.

এইচটিএমএল ডিকোডিংয়ের জন্য, আমি নিম্নলিখিতগুলি ব্যবহার করি:

import re
from htmlentitydefs import name2codepoint
# for some reason, python 2.5.2 doesn't have this one (apostrophe)
name2codepoint['#39'] = 39

def unescape(s):
    "unescape HTML code refs; c.f. http://wiki.python.org/moin/EscapingHtml"
    return re.sub('&(%s);' % '|'.join(name2codepoint),
              lambda m: unichr(name2codepoint[m.group(1)]), s)

আরও জটিল কোনও কিছুর জন্য আমি বিউটিফুলসপ ব্যবহার করি।


20

এনকোডযুক্ত অক্ষরের সেট তুলনামূলকভাবে সীমাবদ্ধ থাকলে ড্যানিয়েলের সমাধানটি ব্যবহার করুন। অন্যথায়, অসংখ্য এইচটিএমএল-পার্সিং লাইব্রেরি ব্যবহার করুন।

আমি বিউটিফুলসপ পছন্দ করি কারণ এটি ত্রুটিযুক্ত এক্সএমএল / এইচটিএমএল পরিচালনা করতে পারে:

http://www.crummy.com/software/BeautifulSoup/

আপনার প্রশ্নের জন্য, তাদের ডকুমেন্টেশনে একটি উদাহরণ রয়েছে

from BeautifulSoup import BeautifulStoneSoup
BeautifulStoneSoup("Sacr&eacute; bl&#101;u!", 
                   convertEntities=BeautifulStoneSoup.HTML_ENTITIES).contents[0]
# u'Sacr\xe9 bleu!'

; BeautifulSoup হেক্স সত্ত্বা রূপান্তর না (& # x65) stackoverflow.com/questions/57708/...
JFS

1
বিউটিফুলসৌপ্পে জন্য, সমতুল্য হবে:from bs4 import BeautifulSoup BeautifulSoup("Sacr&eacute; bl&#101;u!").contents[0]
27:43 এ 3



6

উত্তর হিসাবে ড্যানিয়েলের মন্তব্য:

"টেমপ্লেট রেন্ডারিংয়ের সময় কেবল জাজানোতে পলায়ন ঘটে Therefore অতএব, কোনও আনস্কেপ লাগানোর দরকার নেই - আপনি কেবল টেম্প্লেটিং ইঞ্জিনকে পালাতে না বলুন either {প্রসঙ্গ_ভার | নিরাপদ}} বা {% অটোস্কেপ%} {{প্রসঙ্গ_ভোর}} { % এন্ডোটোসকেপ%} "


কাজ করে, আমার জ্যাঙ্গোর সংস্করণটিতে 'নিরাপদ' নেই except আমি এর পরিবর্তে 'পলায়ন' ব্যবহার করি। আমি ধরে নিলাম এটি একই জিনিস।
উইলিম

1
@ উইলেম: তারা বিপরীত!
আশেরাহ

5

আমি এখানে একটি দুর্দান্ত ফাংশন পেয়েছি: http://snippets.dzone.com/posts/show/4569

def decodeHtmlentities(string):
    import re
    entity_re = re.compile("&(#?)(\d{1,5}|\w{1,8});")

    def substitute_entity(match):
        from htmlentitydefs import name2codepoint as n2cp
        ent = match.group(2)
        if match.group(1) == "#":
            return unichr(int(ent))
        else:
            cp = n2cp.get(ent)

            if cp:
                return unichr(cp)
            else:
                return match.group()

    return entity_re.subn(substitute_entity, string)[0]

পুনরায় ব্যবহারের সুবিধাটি হ'ল আপনি & # 039; এবং & # 39; একই অনুসন্ধান ব্যবহার।
নিল স্ট্যুবলেন

এই হ্যান্ডেল নেই &#xA0;যা একই জিনিস ডিকোড করা উচিত &#160;এবং &nbsp;
মাইক স্যামুয়েল

3

যদি কেউ জ্যাঙ্গো টেম্পলেটগুলির মাধ্যমে এটি করার সহজ উপায় খুঁজছেন তবে আপনি সর্বদা এই জাতীয় ফিল্টার ব্যবহার করতে পারেন:

<html>
{{ node.description|safe }}
</html>

আমার কাছে কোনও বিক্রেতার কাছ থেকে কিছু ডেটা ছিল এবং আমি পোস্ট করা সমস্ত কিছুতে এইচটিএমএল ট্যাগগুলি আসলে রেন্ডার পৃষ্ঠায় লিখিত ছিল যেন আপনি উত্সটি দেখছেন। উপরের কোডটি আমাকে ব্যাপকভাবে সহায়তা করেছে। আশা করি এটি অন্যকে সহায়তা করবে।

চিয়ার্স !!


3

যদিও এটি সত্যিই একটি পুরানো প্রশ্ন, এটি কার্যকর হতে পারে।

জ্যাঙ্গো 1.5.০.5.২০১

In [1]: from django.utils.text import unescape_entities
In [2]: unescape_entities('&lt;img class=&quot;size-medium wp-image-113&quot; style=&quot;margin-left: 15px;&quot; title=&quot;su1&quot; src=&quot;http://blah.org/wp-content/uploads/2008/10/su1-300x194.jpg&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;194&quot; /&gt;')
Out[2]: u'<img class="size-medium wp-image-113" style="margin-left: 15px;" title="su1" src="http://blah.org/wp-content/uploads/2008/10/su1-300x194.jpg" alt="" width="300" height="194" />'

1
এই একমাত্র এটিই এইচটিএমএল সত্তার মতো এনকোডযুক্ত সারোগেট জোড়া ডিকোড করতে সক্ষম হয়েছিল "&#55349;&#56996;"। তারপরে একের পরে result.encode('utf-16', 'surrogatepass').decode('utf-16'), শেষ পর্যন্ত আমার আসল পিছনে ছিল।
পুনরুদ্ধার করুন

1

আমি এটি চিতা উত্স কোডে পেয়েছি ( এখানে )

htmlCodes = [
    ['&', '&amp;'],
    ['<', '&lt;'],
    ['>', '&gt;'],
    ['"', '&quot;'],
]
htmlCodesReversed = htmlCodes[:]
htmlCodesReversed.reverse()
def htmlDecode(s, codes=htmlCodesReversed):
    """ Returns the ASCII decoded version of the given HTML string. This does
        NOT remove normal HTML tags like <p>. It is the inverse of htmlEncode()."""
    for code in codes:
        s = s.replace(code[1], code[0])
    return s

তারা তালিকার বিপরীত কেন তা নিশ্চিত নন, আমি মনে করি যেভাবে তারা এনকোড করেছে সেভাবে এটি করা দরকার, সুতরাং আপনার সাথে এটি বিপরীত হওয়ার দরকারও পড়বে না। এছাড়াও আমি যদি আপনি হয়ে থাকি তবে আমি এইচটিএমএল কোডগুলি তালিকার তালিকার চেয়ে টিপলগুলির একটি তালিকা হিসাবে পরিবর্তন করতাম ... এটি আমার লাইব্রেরিতে চলছে যদিও :)

আমি খেয়াল করেছি আপনার শিরোনামটিও এনকোডের জন্য জিজ্ঞাসা করা হয়েছে, সুতরাং এখানে চিতার এনকোড ফাংশন রয়েছে।

def htmlEncode(s, codes=htmlCodes):
    """ Returns the HTML encoded version of the given string. This is useful to
        display a plain ASCII text string on a web page."""
    for code in codes:
        s = s.replace(code[0], code[1])
    return s

2
তালিকাটি বিপরীত কারণ ডিকোড এবং এনকোড প্রতিস্থাপনগুলি সর্বদা প্রতিসাম্যিকভাবে তৈরি করতে হয়। বিপরীত ছাড়া আপনি যেমন। '& amp; lt;' রূপান্তর করুন '& lt;' এ যান, তারপরে পরবর্তী পদক্ষেপে ভুলভাবে এটি '<' তে রূপান্তর করুন।
বোবিনস

1

আপনি django.utils.html.escape ব্যবহার করতে পারেন

from django.utils.html import escape

something_nice = escape(request.POST['something_naughty'])

ওপিকে অব্যাহতি না দিয়ে অনস্কেপিংয়ের বিষয়ে জিজ্ঞাসা করেছিলেন।
মৃন্ময়

Itsellf শিরোনামে তিনি এনকোডিংয়ের জন্যও বলেছিলেন - আপনার উত্তরটি খুঁজে পেয়েছে এবং এর জন্য কৃতজ্ঞ।
সাইমন স্টেইনবার্গার

1
ওপি যা চেয়েছিল তা নয়, তবে আমি এটি দরকারী বলে মনে করি।
আয়তক্ষেত্র

0

নীচে একটি অজগর ফাংশন যা মডিউল ব্যবহার করে htmlentitydefs। এটি নিখুঁত নয়। htmlentitydefsআমার যে সংস্করণটি রয়েছে তা অসম্পূর্ণ এবং এটি ধরে নিয়েছে যে সমস্ত সত্তা একটি কোডপয়েন্টে ডিকোড করে যা সত্তার জন্য যেমন ভুল&NotEqualTilde; :

http://www.w3.org/TR/html5/named-character-references.html

NotEqualTilde;     U+02242 U+00338    ≂̸

এই সাবধানতা সহ যদিও, এখানে কোড।

def decodeHtmlText(html):
    """
    Given a string of HTML that would parse to a single text node,
    return the text value of that node.
    """
    # Fast path for common case.
    if html.find("&") < 0: return html
    return re.sub(
        '&(?:#(?:x([0-9A-Fa-f]+)|([0-9]+))|([a-zA-Z0-9]+));',
        _decode_html_entity,
        html)

def _decode_html_entity(match):
    """
    Regex replacer that expects hex digits in group 1, or
    decimal digits in group 2, or a named entity in group 3.
    """
    hex_digits = match.group(1)  # '&#10;' -> unichr(10)
    if hex_digits: return unichr(int(hex_digits, 16))
    decimal_digits = match.group(2)  # '&#x10;' -> unichr(0x10)
    if decimal_digits: return unichr(int(decimal_digits, 10))
    name = match.group(3)  # name is 'lt' when '&lt;' was matched.
    if name:
        decoding = (htmlentitydefs.name2codepoint.get(name)
            # Treat &GT; like &gt;.
            # This is wrong for &Gt; and &Lt; which HTML5 adopted from MathML.
            # If htmlentitydefs included mappings for those entities,
            # then this code will magically work.
            or htmlentitydefs.name2codepoint.get(name.lower()))
        if decoding is not None: return unichr(decoding)
    return match.group(0)  # Treat "&noSuchEntity;" as "&noSuchEntity;"


0

জ্যাঙ্গো এবং পাইথনে এই প্রশ্নের সহজ সমাধানটি অনুসন্ধান করে আমি খুঁজে পেয়েছি যে আপনি এইচটিএমএল কোড অব্যাহতি / অনস্কেপ করতে বিল্টইন টিয়ার্স ফাংশন ব্যবহার করতে পারেন।

উদাহরণ

আমি আপনার HTML কোড সংরক্ষিত scraped_htmlএবং clean_html:

scraped_html = (
    '&lt;img class=&quot;size-medium wp-image-113&quot; '
    'style=&quot;margin-left: 15px;&quot; title=&quot;su1&quot; '
    'src=&quot;http://blah.org/wp-content/uploads/2008/10/su1-300x194.jpg&quot; '
    'alt=&quot;&quot; width=&quot;300&quot; height=&quot;194&quot; /&gt;'
)
clean_html = (
    '<img class="size-medium wp-image-113" style="margin-left: 15px;" '
    'title="su1" src="http://blah.org/wp-content/uploads/2008/10/su1-300x194.jpg" '
    'alt="" width="300" height="194" />'
)

জ্যাঙ্গো

আপনার জ্যাঙ্গো> = 1.0 প্রয়োজন

unescape

আপনার স্ক্র্যাপড এইচটিএমএল কোডটি আনস্কেপ করতে আপনি django.utils.text.unescape_entities ব্যবহার করতে পারেন যা:

সমস্ত ইউনিকোড অক্ষরগুলিতে নামযুক্ত এবং সংখ্যাসূচক চরিত্রের রেফারেন্সকে রূপান্তর করুন।

>>> from django.utils.text import unescape_entities
>>> clean_html == unescape_entities(scraped_html)
True

অব্যাহতি

আপনার পরিষ্কার এইচটিএমএল কোড থেকে বাঁচতে আপনি django.utils.html.escape ব্যবহার করতে পারেন যা:

এইচটিএমএল-এ ব্যবহারের জন্য এনকোড করা অ্যাম্পারস্যান্ডস, কোট এবং অ্যাঙ্গেল বন্ধনী সহ প্রদত্ত পাঠ্যটি ফেরত দেয়।

>>> from django.utils.html import escape
>>> scraped_html == escape(clean_html)
True

পাইথন

আপনার পাইথন> = 3.4 দরকার

unescape

আপনার স্ক্র্যাপড এইচটিএমএল কোডটি আনস্কেপ করতে আপনি html.unescape ব্যবহার করতে পারেন যা:

সব নামে এবং সাংখ্যিক অক্ষর রেফারেন্স (যেমন রূপান্তর করুন &gt;, &#62;, &x3e;সংশ্লিষ্ট ইউনিকোড অক্ষর স্ট্রিং s এ)।

>>> from html import unescape
>>> clean_html == unescape(scraped_html)
True

অব্যাহতি

আপনার পরিষ্কার এইচটিএমএল কোড এড়ানোর জন্য আপনি html.escape ব্যবহার করতে পারেন যা:

অক্ষর রূপান্তর করুন &, <এবং >এইচটিএমএল-নিরাপদ সিকোয়েন্স স্ট্রিং s এ।

>>> from html import escape
>>> scraped_html == escape(clean_html)
True
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.