在python中使用IMAP将最近7天的电子邮件从gmail提取到csv时遇到问题。下面是我使用博客帮助构建的代码。
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 6 18:34:56 2017
@author: ravi
"""
import email, getpass, imaplib, os , datetime , csv
detach_dir = '.' # directory where to save attachments (default: current)
user = input("Enter your GMail username:")
pwd = getpass.getpass("Enter your password: ")
# connecting to the gmail imap server
m = imaplib.IMAP4_SSL("imap.gmail.com")
m.login(user,pwd)
m.select("inbox") # here you a can choose a mail box like INBOX instead
m.list()# to get all the mailboxes
date = (datetime.date.today() - datetime.timedelta(7)).strftime("%d-%b-%Y")
result, data = m.search(None, '(SENTSINCE {date})'.format(date=date))
ids = data[0]
id_list = ids.split()
final_list = [ ]
for emailid in id_list:
temp_dict = { }
result, data = m.fetch(id_list, "(RFC822)")# fetching the mail, "`(RFC822)`" means "get the whole stuff", but you can ask for headers only, etc
email_body = data[0][1] # getting the mail content
mail = email.message_from_bytes(email_body) # parsing the mail content to get a mail object
temp_dict['Sender'] = mail["From"]
temp_dict['Subject'] = mail["Subject"]
temp_dict['Date'] = mail["Date"]
print ("["+mail["From"]+"] :" + mail["Subject"] +mail["Date"])
print (temp_dict)
final_list.append(temp_dict)
#exporting the values as .csv
with open('CSV_NAME.csv', 'w', encoding='utf-8', newline = '') as csvfile:
fieldnames = ['Sender','Subject','Date']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter = ',')
writer.writeheader()
for val in final_list:
writer.writerow(val)
在此代码中,数据属于类型列表,不接受类型字节。如何解决这个问题?
UPDATE1: -
尝试了一段新代码。理解解决它的问题是什么?
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 5 19:36:33 2017
@author: ravi
"""
import email, getpass, imaplib, os , datetime , csv
detach_dir = '.' # directory where to save attachments (default: current)
user = input("Enter your GMail username:")
pwd = getpass.getpass("Enter your password: ")
# connecting to the gmail imap server
m = imaplib.IMAP4_SSL("imap.gmail.com")
m.login(user,pwd)
m.select("inbox") # here you a can choose a mail box like INBOX instead
m.list()# to get all the mailboxes
date = (datetime.date.today() - datetime.timedelta(7)).strftime("%d-%b-%Y")
resp, items = m.uid('search', None, '(SENTSINCE {date})'.format(date=date)) # you could filter using the IMAP rules here (check http://www.example-code.com/csharp/imap-search-critera.asp)
items = items[0].split() # getting the mails id
final_list = [ ]
for emailid in items:
temp_dict = { }
resp, data = m.uid('fetch',items,'(RFC822)')# fetching the mail, "`(RFC822)`" means "get the whole stuff", but you can ask for headers only, etc
email_body = data[0][1] # getting the mail content
mail = email.message_from_bytes(email_body) # parsing the mail content to get a mail object
temp_dict['Sender'] = mail["From"]
temp_dict['Subject'] = mail["Subject"]
temp_dict['Date'] = mail["Date"]
print ("["+mail["From"]+"] :" + mail["Subject"] +mail["Date"])
print (temp_dict)
final_list.append(temp_dict)
#exporting the values as .csv
with open('CSV_NAME.csv', 'w', encoding='utf-8', newline = '') as csvfile:
fieldnames = ['Sender','Subject','Date']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames, delimiter = ',')
writer.writeheader()
for val in final_list:
writer.writerow(val)
我收到错误: -
---> 31 resp, data = m.uid('fetch',items,'(RFC822)')# fetching the mail, "`(RFC822)`" means "get the whole stuff", but you can ask for headers only, etc
\Anaconda3\lib\imaplib.py in _command(self, name, *args)
943 if isinstance(arg, str):
944 arg = bytes(arg, self._encoding)
--> 945 data = data + b' ' + arg
946
947 literal = self.literal
TypeError: can't concat bytes to list
无论如何要解决它
答案 0 :(得分:1)
m.uid('fetch',items,'(RFC822)')
项目不能是列表:imaplib命令只接受字符串或字节,但项目是UID列表。
你需要将它按到字符串或字节中。
我不记得列表结果是否是字节或字符串对象的列表,但您可以通过逗号分隔值来获取符合IMAP标准的提取列表。其中一个应该适合你:
uids = ','.join(items)
uids = b','.join(items)