我正在尝试创建一个Python代码,该代码从电子邮件中读取数据,并将其保存到临时txt中。文件。将会有另一个永久文本。文件,其中是临时txt。文件内容将以跳过前6行的形式编写。在此循环期间,将清空临时文件,因此不会多次写入相同的数据。
这是我使用过的代码:
for part in email_message.walk():
if part.get_content_type() == 'text/plain':
body = part.get_payload(decode=True)
save_string = str('C:/Email/file.txt')
myfile = open(save_string, 'a')
myfile.write(str(body)) ## Write to file 2 and then flush this
open ('C:/Email/file.txt','w+') as f:
lines = f.readlines()
open ('C:/Email/newfile.txt','a') as g:
g.writelines(lines[6:])
f.close()
g.close()
myfile.close()# Clear first file
else:
continue
当前的问题是它将电子邮件写入第一个txt。文件,但不会更新第二个txt。文件。但是,当我再次运行代码时,先前的数据将写入第二个txt。这是我不太了解为什么会发生的原因,因为顺序应该正确。预先感谢!
更多代码在这里:
@view_config(route_name='update-data')
def update_view(request):
m = imaplib.IMAP4_SSL('imap.gmail.com')
m.login('gmail@gmail.com', 'password')
m.list()
m.select('inbox')
result, data = m.uid('search', None, 'UNSEEN') # Only unseen mail
i = len(data[0].split()) #space separate string
if i == 0:
return Response('<h3> Data cannot be updated </h3><h4>No new emails</h4><a href="localhost:8888"> Return to the main page </a> ')
for x in range(i):
latest_email_uid = data[0].split()[x]
result, email_data = m.uid('fetch', latest_email_uid, '(RFC822)')
raw_email = email_data[0][1]
raw_email_string = raw_email.decode('utf-8')
email_message = email.message_from_string(raw_email_string)
for part in email_message.walk():
if part.get_content_type() == 'text/plain':
body = part.get_payload(decode=True)
save_string = str('C:/Email/file.txt')
myfile = open(save_string, 'a')
myfile.write(str(body)) ## Write to file 2 and then flush this
open ('C:/Email/file.txt','w+') as f:
lines = f.readlines()
open ('C:/Email/newfile.txt','a') as g:
g.writelines(lines[6:])
f.close()
g.close()
myfile.close()# Clear first file
else:
continue
return Response('<h3>Data update successful</h3>')
编辑
按照我想要的方式进行操作:
for part in email_message.walk():
if part.get_content_type() == 'text/plain':
body = part.get_payload(decode=True)
with open('C:/Email/file.txt', 'a') as myfile: # Opens file.txt and writes the email body
myfile.write(str(body))
with open('C:/Email/file.txt', 'r+') as f: # Opens file.txt again in read mode and reads lines
lines = f.readlines()
with open ('C:/Email/newfile.txt','a') as g: # Writes file.txt contents to newfile.txt, starting from line 6, deletes contents of the first file
g.writelines(lines[6:])
f.truncate(0)
else:
continue
答案 0 :(得分:2)
您需要先关闭myfile
,然后再尝试重新打开它,并且应该以{{1}}模式重新打开它。试试这样的东西
read
但是最好使用
for part in email_message.walk():
if part.get_content_type() == 'text/plain':
body = part.get_payload(decode=True)
save_string = str('C:/Email/file.txt')
myfile = open(save_string, 'a')
myfile.write(str(body)) ## Write to file 2 and then flush this
myfile.close()
open ('C:/Email/file.txt','r') as f:
lines = f.readlines()
open ('C:/Email/newfile.txt','a') as g:
g.writelines(lines[6:])
f.close()
g.close()
上下文管理器打开文件,在这种情况下,您不必担心关闭文件
with
答案 1 :(得分:1)
您正在尝试附加到此处不存在的文件:
open ('C:/Email/newfile.txt','a') as g:
g.writelines(lines[6:])
我建议您这样做:
if os.path.exists('C:/Email/newfile.txt'):
g = open ('C:/Email/newfile.txt','a')
else:
g = open ('C:/Email/newfile.txt','w+')
g.writelines(lines[6:])
答案 2 :(得分:1)
让我们退后一步,评估代码的预期目标。您希望它从根本上解析电子邮件文件的内容,然后从第7行开始写入文本/纯格式的内容。因此,我们可以放心地假设我们正在处理字符串类型。
现在,您的实现使用一个临时文件作为中间人来获取7+行。但是,您实际上可以通过解析字符串本身并抓取7+行来跳过临时文件的使用。只需用\n
(换行符转义序列)分割字符串,然后从第7+行开始重建字符串。
让我们假设您的电子邮件部分的内容为:
>>> mystr = "This is\na message\nwith\nmultiple\nlines\nin the\nstring.\n\nEnd of file"
如果我打印出来,它将显示:
>>> print(mystr)
This is
a message
with
multiple
lines
in the
string.
End of file
您现在可以简单地分割字符串,用\n
分割,这将返回一个列表,其中每个元素代表一行。从那里,您可以仅抓取7条及以上的线,然后使用\n
重新加入元素。
>>> mystr_split = mystr.split('\n')
>>> mystr_split
['This is', 'a message', 'with', 'multiple', 'lines', 'in the', 'string.', '', 'End of file']
>>> to_write = '\n'.join(mystr_split[6:])
>>> to_write
'string.\n\nEnd of file'
>>> print(to_write)
string.
End of file
因此,回到您的问题,您可以简单地解析电子邮件的文本/纯文本内容,而无需使用临时文件即可将第7行以上的内容写入一个文件中。
for part in email_message.walk():
if part.get_content_type() == 'text/plain':
body = part.get_payload(decode=True)
save_string = r'C:/Email/file.txt'
body_split = body.split('\n')
to_write = '\n'.join(body_split[6:])
with open(save_string, 'w') as f:
f.write(to_write)