【问题标题】:Why HTML convert python output '<' = &lt, '>' = &gt?为什么 HTML 转换 python 输出 '<' = &lt, '>' = &gt?
【发布时间】:2017-05-30 21:18:30
【问题描述】:

我创建了一个脚本,它可以发送邮件,其中特定的输出来自服务器。 我拆分了这个输出并将每个元素发送到一个 html 单元格。 我还为表格创建了一个标题,如下所示:

def get_html_table_header(*column_names):
    header_string = '<tr width=79 style="background:#3366FF;height:23.25pt;font-size:8.0pt;font-family:Arial,sans-serif;color:white;font-weight:bold;" >'
    for column in column_names:
        if column is not None:
            header_string += '<td>' + column + '</td>'

    header_string += '</tr>'
    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')

当我在 linux konsole 中打印这个函数的结果时,它看起来像这样:

<tr width=79 style="background:#3366FF;height:23.25pt;font-size:8.0pt;font-family:Arial,sans-serif;color:white;font-weight:bold;" ><td>Num. Row</td><td>Cell1</td><td>Cell2</td><td>Cell3</td><td>Comment (enter your feedback below)</td><td>Cell4</td><td>Cell5</td><td>Cell6</td><td>Cell7</td><td>Cell8</td><td>Cell9</td><td>Cell10</td></tr>

当我收到邮件时,来源如下:

<tr width="79" style="background:#3366FF;height:23.25pt;font-size:8.0pt;font-family:Arial,sans-serif;color:white;font-weight:bold;"><td>Num. Row</td><td>Cell1</td><td>Cell2</td><td>Cell3</td><td>Comment (enter your feedback below)</td><td>Cell4</td><td>Cell5</td><td>Cell6</td><td>Cell7</td><td>Cell8</td><td>Cell9</td>&lt; td&gt;Cell10</td></tr>

要构建电子邮件正文,我正在使用函数:

def build_email_body(CRs_list):
    global criterial_number

    if 0 == len(CRs_list):
        return None

    email_body = ''
    email_body += '<html><head><title>My Title</title></head><body>'
    email_body += '<p align="center"><font color="#176b54" size="+2"><b>Some info</b></font></p>'
    email_body += '<p align="center"><font color="#176b54" size="+1">Another info</font></p>'
    email_body += '<table align="center" BORDER=1 CELLSPACING=2 CELLPADDING=2 COLS=3 WIDTH="100%">'
    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 += '</table>'

    email_body += '</table><br><p align="left"><font color="#176b54" size="+1"><b>=> This is an automatic generated email via script<br>'
    email_body += '<br><br>Have a nice day!</b></font></p><br></body></html>'

    return email_body

要发送电子邮件,我正在使用函数:

def send_email(body, recipients, subject, file):

    #inform just sender
    if None == body:
        body = "WARNING -> NO entries retrieved after 5 retries<br>CRAU output:<br>" + dct_newCRs_output + "<br>" + duration
        #override recipients to not set junk info
        recipients = sender

    email = Email(SMTP_SERVER, SENDER, recipients, _CC, subject, body, 'html', file)
    email.send()

send() 是从 Email 类导入的:

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()

我希望有足够的信息。 有人可以向我解释一下,为什么会发生这种情况,我该如何解决?

【问题讨论】:

  • 请说明您发送邮件的方式。也许错误发生在那里。
  • 作为旁注,您应该避免在这样的循环中连接字符串。你应该建立一个列表,完成后''.join()它。
  • @spectras 为什么?只是好奇。
  • 它避免了构建所有中间字符串。诚然,CPython 的最新版本现在对此进行了很好的优化,但对于旧版本或 pypy 等其他 python 实现而言,情况并非如此。
  • @RouvenB。我编辑了我的问题!谢谢!

标签: python html outlook


【解决方案1】:

您的代码看起来正确,问题出在其他地方。

&amp;lt; 是将&lt; 作为文本添加到 HTML 文档时得到的结果(因为 &lt; 表示“开始新元素”,您需要以纯文本形式转义该字符)。

这里有趣的部分是为什么它在整个字符串中只发生一次。如果所有的&lt; 都被替换了,我猜你不小心将表格作为文本添加到邮件的 HTML 正文中。

&amp;lt; td&amp;gt; 中的空格可能是一个线索:邮件每行不应超过 72 个字符。那么也许一些邮件服务器包装了 HTML?众所周知,Outlook 会对其收到的邮件造成很大影响。

尝试将 HTML 代码作为多部分附件发送。见Sending HTML email using Python

【讨论】:

  • 这实际上是发生在我身上的事情,所以我认为 OP 应该看看这个
  • 这里也一样,我在中间加了一个\n,问题就解决了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
相关资源
最近更新 更多