Problem deleting emails in gmail using imaplib

2019-02-13 23:42发布

问题:

I try to remove message from inbox folder and all alright, but when i switched to All Mail folder the removing does not work. expunge() method returns ('OK', [None]) and message was not removed:

>>>import imaplib
>>>server = imaplib.IMAP4_SSL('imap.gmail.com','993')
>>>server.login('likvidator89@gmail.com','Password')
>>>server.select('inbox')
>>>for i in server.search(None,'all')[1][0].split():
...    print i+"\n"+server.fetch(i,'(BODY[HEADER.FIELDS (Subject)])')[1][0][1]
...
#  that how i know what UID hame my message? I select by subject
#....
#28
#Subject: 1 Question Has 1 Answer - Stack Overflow
#
#
#29
#Subject: 2222222222
#...
>>>server.store(29,'+FLAGS','\\Deleted')
#('OK', ['29 (FLAGS (\\Seen \\Deleted))'])
>>>server.expunge()
#('OK', ['29'])
>>> server.select('[Gmail]/All Mail')
('OK', ['47'])
>>> for i in server.search(None,'all')[1][0].split():
...  print i+"\n"+server.fetch(i,'(BODY[HEADER.FIELDS (Subject)])')[1][0][1]
... 
#....
#
#46
#Subject: 2222222222
#
#
#47
#Subject: 3333333333333333
#
#....
>>> server.store(47,'+FLAGS','\\Deleted')
('OK', ['47 (FLAGS (\\Seen \\Deleted))'])
>>> server.expunge()
('OK', [None])

回答1:

As it says on the gmail blog site, Google's implementation of IMAP is a bit different. When you follow the instructions for getting more usual semantics, does it help?

There are also some more obscure options for those of you who want to make Gmail's IMAP work more like traditional IMAP providers: you can turn off auto-expunge or trash messages when they're no longer visible through IMAP.

The IMAP protocol allows messages to be marked for deletion, a sort of limbo state where a message is still present in the folder but slated to be deleted the next time the folder is expunged. In our standard IMAP implementation, when you mark a message as deleted, Gmail doesn't let it linger in that state -- it deletes (or auto-expunges) it from the folder right away. If you want the two-stage delete process, after you've enabled this Lab, just select 'Do not automatically expunge messages' under the 'Forwarding and POP/IMAP' tab in Settings.

Similarly, most IMAP systems don't share Gmail's concept of archiving messages (sending messages to the [Gmail]/All Mail folder rather than [Gmail]/Trash). If you'd prefer that deleted messages not remaining in any other visible IMAP folders are sent to [Gmail]/Trash instead, Advanced IMAP Controls lets you set your preferences this way. In the 'IMAP Access:' section of the 'Forwarding and POP/IMAP' tab, find the 'When a message is deleted from the last visible IMAP folder:' option. Select 'Move the message to the Gmail Trash.' If you want to take it one step further, you can select 'Immediately delete the message forever.'



回答2:

it moves all the mail in a given gmail label to the gmail Trash

#!usr/bin/python
import email, imaplib

user = 'xxx'
pwd = 'xxx'

m = imaplib.IMAP4_SSL("imap.gmail.com")
m.login(user,pwd)

m.select("some_gmail_label")
m.store("1:*",'+X-GM-LABELS', '\\Trash')

m.expunge() # should be useless, but gmail server says it is ok

Remember to refresh your gmail interface cause it has cache



回答3:

With Gmail advanced IMAP controls you can set what happens to messages when you delete them over IMAP.

Just enable "Advanced IMAP Controls" in Gmail Labs. The settings page will look like this:

Then when you mark a message as deleted and expunge as per this answer it will be moved to the bin, permanently deleted, or archived to "All Mail" depending on what setting you selected.



回答4:

Here is one that works with Gmail and does it very quickly (without store in a for loop). Tailor this as you wish, but the idea is all there on how to use select/search and then perform a store, or just select on its own for all items with a specific label/folder:

#!/bin/python

import datetime
import imaplib

m = imaplib.IMAP4_SSL("imap.gmail.com")  # server to connect to
print "Connecting to mailbox..."
m.login('gmail@your_gmail.com', 'your_password')

print m.select('[Gmail]/All Mail')  # required to perform search, m.list() for all lables, '[Gmail]/Sent Mail'
before_date = (datetime.date.today() - datetime.timedelta(365)).strftime("%d-%b-%Y")  # date string, 04-Jan-2013
typ, data = m.search(None, '(BEFORE {0})'.format(before_date))  # search pointer for msgs before before_date

if data != ['']:  # if not empty list means messages exist
    no_msgs = data[0].split()[-1]  # last msg id in the list
    print "To be removed:\t", no_msgs, "messages found with date before", before_date
    m.store("1:{0}".format(no_msgs), '+X-GM-LABELS', '\\Trash')  # move to trash
    print "Deleted {0} messages. Closing connection & logging out.".format(no_msgs)
else:
    print "Nothing to remove."

#This block empties trash, remove if you want to keep, Gmail auto purges trash after 30 days.
print("Emptying Trash & Expunge...")
m.select('[Gmail]/Trash')  # select all trash
m.store("1:*", '+FLAGS', '\\Deleted')  #Flag all Trash as Deleted
m.expunge()  # not need if auto-expunge enabled

print("Done. Closing connection & logging out.")
m.close()
m.logout()
print "All Done."