为什么 HTML 转换 python 输出 '<' = <, '>' = >?
Why HTML convert python output '<' = <, '>' = >?
我创建了一个脚本,用于发送从服务器获取的特定输出的邮件。
我拆分了这个输出并将每个元素发送到 html 单元格。
我还为 table 创建了一个 header,看起来像这样:
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>< td>Cell10</td></tr>
要构建电子邮件 body 我正在使用函数:
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() 从 class 邮箱导入:
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()
我希望有足够的信息。
谁能给我解释一下,为什么会这样,我该如何解决?
您的代码看起来是正确的,问题出在其他地方。
<
是将 <
作为文本添加到 HTML 文档时得到的结果(因为 <
表示 "start new element",您需要转义这个字符在纯文本中)。
这里有趣的部分是为什么它在整个字符串中只发生一次。如果所有 <
都被替换,我的猜测是您不小心将 table 作为文本添加到邮件的 HTML 正文中。
也许 < td>
中的 space 是一个线索:邮件每行不应超过 72 个字符。所以也许某些邮件服务器包装了 HTML?众所周知,Outlook 会将其收到的邮件搞得一团糟。
尝试将 HTML 代码作为多部分附件发送。参见 Sending HTML email using Python
我创建了一个脚本,用于发送从服务器获取的特定输出的邮件。 我拆分了这个输出并将每个元素发送到 html 单元格。 我还为 table 创建了一个 header,看起来像这样:
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>< td>Cell10</td></tr>
要构建电子邮件 body 我正在使用函数:
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() 从 class 邮箱导入:
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()
我希望有足够的信息。 谁能给我解释一下,为什么会这样,我该如何解决?
您的代码看起来是正确的,问题出在其他地方。
<
是将 <
作为文本添加到 HTML 文档时得到的结果(因为 <
表示 "start new element",您需要转义这个字符在纯文本中)。
这里有趣的部分是为什么它在整个字符串中只发生一次。如果所有 <
都被替换,我的猜测是您不小心将 table 作为文本添加到邮件的 HTML 正文中。
也许 < td>
中的 space 是一个线索:邮件每行不应超过 72 个字符。所以也许某些邮件服务器包装了 HTML?众所周知,Outlook 会将其收到的邮件搞得一团糟。
尝试将 HTML 代码作为多部分附件发送。参见 Sending HTML email using Python