Comment puis-je me connecter à Gmail et déterminer quels messages comportent des pièces jointes ? Je veux ensuite télécharger chaque pièce jointe, en imprimant le sujet et l'origine de chaque message au fur et à mesure que je le traite.
Réponses
Trop de publicités?C'est difficile :-)
import email, getpass, imaplib, os
detach_dir = '.' # directory where to save attachments (default: current)
user = raw_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("[Gmail]/All Mail") # here you a can choose a mail box like INBOX instead
# use m.list() to get all the mailboxes
resp, items = m.search(None, "ALL") # 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
for emailid in items:
resp, data = m.fetch(emailid, "(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_string(email_body) # parsing the mail content to get a mail object
#Check if any attachments at all
if mail.get_content_maintype() != 'multipart':
continue
print "["+mail["From"]+"] :" + mail["Subject"]
# we use walk to create a generator so we can iterate on the parts and forget about the recursive headach
for part in mail.walk():
# multipart are just containers, so we skip them
if part.get_content_maintype() == 'multipart':
continue
# is this part an attachment ?
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
counter = 1
# if there is no filename, we create one with a counter to avoid duplicates
if not filename:
filename = 'part-%03d%s' % (counter, 'bin')
counter += 1
att_path = os.path.join(detach_dir, filename)
#Check if its already there
if not os.path.isfile(att_path) :
# finally write the stuff
fp = open(att_path, 'wb')
fp.write(part.get_payload(decode=True))
fp.close()
Wowww ! C'était quelque chose ;-) Mais essayez la même chose en Java, juste pour le plaisir !
Au fait, j'ai testé cela dans un shell, il est donc probable que certaines erreurs subsistent.
Profitez de
EDITAR:
Comme les noms de boîtes aux lettres peuvent changer d'un pays à l'autre, je recommande de faire m.list()
et de choisir un élément dans la liste avant m.select("the mailbox name")
pour éviter cette erreur :
imaplib.error : la commande SEARCH est illégale dans l'état AUTH, elle est uniquement autorisée dans l'état SELECTED. états SELECTED
#!/usr/bin/env python
"""Save all attachments for given gmail account."""
import os, sys
from libgmail import GmailAccount
ga = GmailAccount("your.account@gmail.com", "pA$$w0Rd_")
ga.login()
# folders: inbox, starred, all, drafts, sent, spam
for thread in ga.getMessagesByFolder('all', allPages=True):
for msg in thread:
sys.stdout.write('.')
if msg.attachments:
print "\n", msg.id, msg.number, msg.subject, msg.sender
for att in msg.attachments:
if att.filename and att.content:
attdir = os.path.join(thread.id, msg.id)
if not os.path.isdir(attdir):
os.makedirs(attdir)
with open(os.path.join(attdir, att.filename), 'wb') as f:
f.write(att.content)
non testé
- Assurez-vous que les TOS autorisent de tels scripts, sinon votre compte sera suspendu.
- Il y a peut-être de meilleures options : Mode hors ligne de GMail, Thunderbird + ExtractExtensions, GmailFS, Gmail Drive, etc.
Jetez un coup d'œil à Mail::Webmail::Gmail :
OBTENIR DES PIÈCES JOINTES
Il y a deux façons d'obtenir une pièce jointe :
1 -> En envoyant une référence à une pièce jointe spécifique retournée par get_indv_email
# Creates an array of references to every attachment in your account
my $messages = $gmail->get_messages();
my @attachments;
foreach ( @{ $messages } ) {
my $email = $gmail->get_indv_email( msg => $_ );
if ( defined( $email->{ $_->{ 'id' } }->{ 'attachments' } ) ) {
foreach ( @{ $email->{ $_->{ 'id' } }->{ 'attachments' } } ) {
push( @attachments, $gmail->get_attachment( attachment => $_ ) );
if ( $gmail->error() ) {
print $gmail->error_msg();
}
}
}
}
2 -> Ou en envoyant l'ID de la pièce jointe et l'ID du message
#retrieve specific attachment
my $msgid = 'F000000000';
my $attachid = '0.1';
my $attach_ref = $gmail->get_attachment( attid => $attachid, msgid => $msgid );
( Retourne une référence à un scalaire qui contient les données de la pièce jointe. )
Dans gmail, vous pouvez filtrer sur "has:attachment", utilisez-le pour identifier les messages que vous devriez recevoir lors du test. Notez que cela semble donner à la fois des messages avec des fichiers joints (icône en forme de trombone affichée) et des images jointes en ligne (pas de trombone affiché).
Il n'y a pas d'API Gmail, donc IMAP ou POP sont vos seules véritables options. Le site API JavaMail peut être d'une certaine utilité ainsi que cet article très laconique sur les téléchargement de pièces jointes à partir d'IMAP à l'aide de Perl . Quelques questions précédentes ici sur SO peut aussi aider.
Ce site Exemple de PHP peut aussi aider. Malheureusement, d'après ce que je vois, l'en-tête imap_header ne contient pas d'informations sur les pièces jointes. Il faut donc télécharger le corps du message pour pouvoir voir le champ X-Attachment-Id. (quelqu'un peut me prouver que j'ai tort).
- Réponses précédentes
- Plus de réponses