title: Why HTML convert python output '<' = &lt, '>' = &gt?
body: <p>I created a script who send mail whith a specific output took from a server.
  I splited this output and each element I sent it to a html cell.
  I also created a header for the table what is looks like that:</p>
  
  <pre><code>def get_html_table_header(*column_names):
      header_string = '&lt;tr width=79 style="background:#3366FF;height:23.25pt;font-size:8.0pt;font-family:Arial,sans-serif;color:white;font-weight:bold;" &gt;'
      for column in column_names:
          if column is not None:
              header_string += '&lt;td&gt;' + column + '&lt;/td&gt;'
  
      header_string += '&lt;/tr&gt;'
      return header_string 
  
  def get_concrete_html_table_header():
      return get_html_table_header('Num. Row','Cell1','Cell2','Cell3','Comment (enter your feedback below)','Cell4','Cell5','Cell6','Cell7','Cell8','Cell9','Cell10')
  </code></pre>
  
  <p>When I print the result of this function in linux konsole, it looks like that:</p>
  
  <pre><code>&lt;tr width=79 style="background:#3366FF;height:23.25pt;font-size:8.0pt;font-family:Arial,sans-serif;color:white;font-weight:bold;" &gt;&lt;td&gt;Num. Row&lt;/td&gt;&lt;td&gt;Cell1&lt;/td&gt;&lt;td&gt;Cell2&lt;/td&gt;&lt;td&gt;Cell3&lt;/td&gt;&lt;td&gt;Comment (enter your feedback below)&lt;/td&gt;&lt;td&gt;Cell4&lt;/td&gt;&lt;td&gt;Cell5&lt;/td&gt;&lt;td&gt;Cell6&lt;/td&gt;&lt;td&gt;Cell7&lt;/td&gt;&lt;td&gt;Cell8&lt;/td&gt;&lt;td&gt;Cell9&lt;/td&gt;&lt;td&gt;Cell10&lt;/td&gt;&lt;/tr&gt;
  </code></pre>
  
  <p>When I receive the email, source looks like that:</p>
  
  <pre><code>&lt;tr width="79" style="background:#3366FF;height:23.25pt;font-size:8.0pt;font-family:Arial,sans-serif;color:white;font-weight:bold;"&gt;&lt;td&gt;Num. Row&lt;/td&gt;&lt;td&gt;Cell1&lt;/td&gt;&lt;td&gt;Cell2&lt;/td&gt;&lt;td&gt;Cell3&lt;/td&gt;&lt;td&gt;Comment (enter your feedback below)&lt;/td&gt;&lt;td&gt;Cell4&lt;/td&gt;&lt;td&gt;Cell5&lt;/td&gt;&lt;td&gt;Cell6&lt;/td&gt;&lt;td&gt;Cell7&lt;/td&gt;&lt;td&gt;Cell8&lt;/td&gt;&lt;td&gt;Cell9&lt;/td&gt;&amp;lt; td&amp;gt;Cell10&lt;/td&gt;&lt;/tr&gt;
  </code></pre>
  
  <p>To build email body I`m using function:</p>
  
  <pre><code>def build_email_body(CRs_list):
      global criterial_number
  
      if 0 == len(CRs_list):
          return None
  
      email_body = ''
      email_body += '&lt;html&gt;&lt;head&gt;&lt;title&gt;My Title&lt;/title&gt;&lt;/head&gt;&lt;body&gt;'
      email_body += '&lt;p align="center"&gt;&lt;font color="#176b54" size="+2"&gt;&lt;b&gt;Some info&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;'
      email_body += '&lt;p align="center"&gt;&lt;font color="#176b54" size="+1"&gt;Another info&lt;/font&gt;&lt;/p&gt;'
      email_body += '&lt;table align="center" BORDER=1 CELLSPACING=2 CELLPADDING=2 COLS=3 WIDTH="100%"&gt;'
      email_body += get_concrete_html_table_header()
  
      for CR in CRs_list:
           email_body +=  get_html_table_row()#create row for every output received(11 cells for every output, according with the header)
  
      email_body += '&lt;/table&gt;'
  
      email_body += '&lt;/table&gt;&lt;br&gt;&lt;p align="left"&gt;&lt;font color="#176b54" size="+1"&gt;&lt;b&gt;=&gt; This is an automatic generated email via script&lt;br&gt;'
      email_body += '&lt;br&gt;&lt;br&gt;Have a nice day!&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;br&gt;&lt;/body&gt;&lt;/html&gt;'
  
      return email_body
  </code></pre>
  
  <p>To send email I`m using function:</p>
  
  <pre><code>def send_email(body, recipients, subject, file):
  
      #inform just sender
      if None == body:
          body = "WARNING -&gt; NO entries retrieved after 5 retries&lt;br&gt;CRAU output:&lt;br&gt;" + dct_newCRs_output + "&lt;br&gt;" + duration
          #override recipients to not set junk info
          recipients = sender
  
      email = Email(SMTP_SERVER, SENDER, recipients, _CC, subject, body, 'html', file)
      email.send()
  </code></pre>
  
  <p>send() is imported from class Email:</p>
  
  <pre><code>import os, smtplib
  from email import encoders
  from email.mime.audio import MIMEAudio
  from email.mime.base import MIMEBase
  from email.mime.image import MIMEImage
  from email.mime.multipart import MIMEMultipart
  from email.mime.text import MIMEText
  import mimetypes
  
  class Email:
      __config = {}
      def __init__(self, smtp_server, sender, recipients, cc, subject, body, body_type, attachments=None):
          self.__config = {'smtp_server': smtp_server,
              'sender': sender,
              'recipients': recipients,
              'cc': cc,
              'subject': subject,
              'body':body,
              'body_type':body_type,  #plain|html
              'attachments':attachments #list of files
          }       
  
      def getSmtpServer(self):
          return self.__config.get('smtp_server')
      def getSender(self):
          return self.__config.get('sender')
      def getRecipients(self):
          return self.__config.get('recipients')
      def getCc(self):
          return self.__config.get('cc')
      def getSubject(self):
          return self.__config.get('subject')
      def getBody(self):
          return self.__config.get('body')
      def getBodyType(self):
          return self.__config.get('body_type')
      def getAttachments(self):
          return self.__config.get('attachments')
  
  
  
      def setSmtpServer(self, host):
          self.__config['smtp_server'] = smtp_server
          return self
      def setSender(self, sender):
          self.__config['sender'] = sender
          return self
      def setRecipients(self, recipients):
          self.__config['recipients'] = recipients
          return self
      def setCc(self, cc):
          self.__config['cc'] = cc
          return self
      def setSubject(self, subject):
          self.__config['subject'] = subject
          return self
      def setBody(self, body):
          self.__config['body'] = body
          return selfMIMEMultipart
      def setBodyType(self, body_type):
          self.__config['body_type'] = body_type
          return self
      def setAttachments(self, attachments):
          self.__config['attachments'] = attachments
          return self
  
      def attachFilesToEmail(self, attachments, msg):
          if None == attachments:
              tmpmsg = msg
              msg = MIMEMultipart()
              msg.attach(tmpmsg)
          if None != attachments:
              for fname in attachments:
                  if not os.path.exists(fname):
                      print "File '%s' does not exist.  Not attaching to email." % fname
                      continue
                  if not os.path.isfile(fname):
                      print "Attachment '%s' is not a file.  Not attaching to email." % fname
                      continue
                  # Guess at encoding type
                  ctype, encoding = mimetypes.guess_type(fname)
                  if ctype is None or encoding is not None:
                      # No guess could be made so use a binary type.
                      ctype = 'application/octet-stream'
                  maintype, subtype = ctype.split('/', 1)
                  if maintype == 'text':
                      fp = open(fname)
                      attach = MIMEText(fp.read(), _subtype=subtype)
                      fp.close()
                  elif maintype == 'image':
                      fp = open(fname, 'rb')
                      attach = MIMEImage(fp.read(), _subtype=subtype)
                      fp.close()
                  elif maintype == 'audio':
                      fp = open(fname, 'rb')
                      attach = MIMEAudio(fp.read(), _subtype=subtype)
                      fp.close()
                  else:
                      fp = open(fname, 'rb')
                      attach = MIMEBase(maintype, subtype)
                      attach.set_payload(fp.read())
                      fp.close()
                      # Encode the payload using Base64
                      encoders.encode_base64(attach)
                  # Set the filename parameter
                  filename = os.path.basename(fname)
                  attach.add_header('Content-Disposition', 'attachment', filename=filename)
                  msg.attach(attach)
  
      def send(self):
          # Create message container - the correct MIME type is multipart/alternative.
          msg = MIMEMultipart('alternative')
          msg['Subject'] = self.getSubject()
          msg['From'] = self.getSender()
          msg['To'] = self.getRecipients()
          msg['CC'] = self.getCc()
  
          # Record the MIME types of both parts - text/plain and text/html.
          #part1 = MIMEText(text, 'plain')
          #part2 = MIMEText(html, 'html')
          part = MIMEText(self.getBody(), self.getBodyType())
  
          # Attach parts into message container.
          # According to RFC 2046, the last part of a multipart message, in this case
          # the HTML message, is best and preferred.
          msg.attach(part)
  
          # Add attachments, if any
          self.attachFilesToEmail(self.getAttachments(), msg)
  
          # Send the message via local SMTP server.
          s = smtplib.SMTP(self.getSmtpServer())
          # sendmail function takes 3 arguments: sender's address, recipient's address
          # and message to send - here it is sent as one string.
          s.sendmail(self.getSender(), (self.getRecipients() + self.getCc()).split(","), msg.as_string())
          s.quit()
  </code></pre>
  
  <p>I hope is enough information.
  Can someone explain to me, why is happening this and how can I fix it?</p>