4

I need to convert any html entity into its ASCII equivalent using Python. My use case is that I am cleaning up some HTML used to build emails to create plaintext emails from the HTML.

Right now, I only really know how to create unicode from these entities when I need ASCII (I think) so that the plaintext email reads correctly with things like accented characters. I think a basic example is the html entity "& aacute;" or á being encoded into ASCII.

Furthermore, I'm not even 100% sure that ASCII is what I need for a plaintext email. As you can tell, I'm completely lost on this encoding stuff.

4 Answers 4

8

Here is a complete implementation that also handles unicode html entities. You might find it useful.

It returns a unicode string that is not ascii, but if you want plain ascii, you can modify the replace operations so that it replaces the entities to empty string.

def convert_html_entities(s):
    matches = re.findall("&#\d+;", s)
    if len(matches) > 0:
        hits = set(matches)
        for hit in hits:
            name = hit[2:-1]
            try:
                entnum = int(name)
                s = s.replace(hit, unichr(entnum))
            except ValueError:
                pass

    matches = re.findall("&#[xX][0-9a-fA-F]+;", s)
    if len(matches) > 0:
        hits = set(matches)
        for hit in hits:
            hex = hit[3:-1]
            try:
                entnum = int(hex, 16)
                s = s.replace(hit, unichr(entnum))
            except ValueError:
                pass

    matches = re.findall("&\w+;", s)
    hits = set(matches)
    amp = "&"
    if amp in hits:
        hits.remove(amp)
    for hit in hits:
        name = hit[1:-1]
        if htmlentitydefs.name2codepoint.has_key(name):
            s = s.replace(hit, unichr(htmlentitydefs.name2codepoint[name]))
    s = s.replace(amp, "&")
    return s 

Edit: added matching for hexcodes. I've been using this for a while now, and ran into my first situation with ' which is a single quote/apostrophe.

Sign up to request clarification or add additional context in comments.

1 Comment

Nice answer. It seems there should be something in a standard module to do this.
2

ASCII is the American Standard Code for Information Interchange and does not include any accented letters. Your best bet is to get Unicode (as you say you can) and encode it as UTF-8 (maybe ISO-8859-1 or some weird codepage if you're dealing with seriously badly coded user-agents/clients, sigh) -- the content type header of that part together with text/plain can express what encoding you've chosen to use (I do recommend trying UTF-8 unless you have positively demonstrated it cannot work -- it's almost universally supported these days and MUCH more flexible than any ISO-8859 or "codepage" hack!).

1 Comment

This worked well moving stuff to unicode first and then on to UTF-8, at least in my preliminary tests. We'll have to send out some mail tomorrow and see how it plays in the email clients. Thanks for the detailed explanation as to what I might really want as well.
1

You can use the htmlentitydefs package:

import htmlentitydefs
print htmlentitydefs.entitydefs['aacute']

Basically, entitydefs is just a dictionary, and you can see this by printing it at the python prompt:

from pprint import pprint 
pprint htmlentitydefs.entitydefs

3 Comments

that gives you (roughly) ISO-8859-1 codes -- which these days is a hopelessly obsolete approach even for a stubborn "western/european supremacist" (for example, even the euro sign doesn't fit there...!!!). htmlentitydefs.name2codepoint, which uniformly gives you the numeric codepoint (which you can turn into a unicode string of length 1 with unichr -- and then .encode as you wish), is vastly preferable.
Thanks for input ars. It certainly seems to get me the ASCII-ish stuff that I asked for, but I also needed a little more guidance on my use case as well.
@aezell: Sure thing. I prefer Alex's answer, too, for the big picture, as well as his specific suggestions to my own answer. :)
0

We put up a little module with agazso's function:

http://github.com/ARTFL/util/blob/master/ents.py

We find agazso's function to faster than the alternatives for ent conversion. Thanks for posting it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.