Gmailに接続して、添付ファイルのあるメッセージを特定するにはどうすればよいですか?次に、各添付ファイルをダウンロードし、処理するメッセージごとにSubject:およびFrom:を印刷します。
ハードなもの:-)
_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()
_
すごい!それは何かでした。 ;-)しかし、Javaでも同じことを試してみてください。
ところで、私はそれをシェルでテストしたので、いくつかのエラーが残っている可能性があります。
楽しい
編集:
メールボックスの名前は国によって異なるため、このエラーを回避するために、m.list()
を実行し、m.select("the mailbox name")
の前にアイテムを選択することをお勧めします。
imaplib.error:状態AUTHではコマンドSEARCHが無効、選択済みの状態でのみ許可
私はPerlの専門家ではありませんが、GMailがIMAPとPOP3をサポートしていることを知っています。2つのプロトコルは完全に標準であり、まさにそれを可能にします。
多分それはあなたが始めるのに役立ちます。
#!/usr/bin/env python
"""Save all attachments for given gmail account."""
import os, sys
from libgmail import GmailAccount
ga = GmailAccount("[email protected]", "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)
未検証
Mail :: Webmail :: Gmail :を見てください
添付ファイルの取得
添付ファイルを取得するには2つの方法があります。
1-> 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->または、添付ファイルIDとメッセージIDを送信する
#retrieve specific attachment
my $msgid = 'F000000000';
my $attachid = '0.1';
my $attach_ref = $gmail->get_attachment( attid => $attachid, msgid => $msgid );
(添付ファイルからのデータを保持するスカラーへの参照を返します。)
Gmail内では、「has:attachment」でフィルタリングし、それを使用して、テスト時に取得するメッセージを特定できます。これにより、添付ファイル(Paperclipアイコンが表示)とインライン添付画像(Paperclipは表示なし)の両方のメッセージが表示されることに注意してください。
Gmail APIはないため、IMAPまたはPOPが唯一の本当のオプションです。 JavaMail API は、 Perlを使用してIMAPから添付ファイルをダウンロードする に関するこの非常に簡潔な記事と同様に、いくらかの助けになるかもしれません。いくつかの 前の質問 ここでSOも役立つかもしれません。
この PHPの例 も役立つ場合があります。残念なことに、imap_headerには添付情報が含まれていないため、X-Attachment-Idフィールドを表示するには本文をダウンロードする必要があります。 (誰かが間違っていることを証明してください)。
いずれかがpython 3.3に更新した場合、 [〜#〜] here [〜#〜] から2.7スクリプトを取得し、3.3に更新しました。 gmailが情報を返す方法に関するいくつかの問題。
# Something in lines of http://stackoverflow.com/questions/348630/how-can-i-download-all-emails-with-attachments-from-gmail
# Make sure you have IMAP enabled in your gmail settings.
# Right now it won't download same file name twice even if their contents are different.
# Gmail as of now returns in bytes but just in case they go back to string this line is left here.
import email
import getpass, imaplib
import os
import sys
import time
detach_dir = '.'
if 'attachments' not in os.listdir(detach_dir):
os.mkdir('attachments')
userName = input('Enter your GMail username:\n')
passwd = getpass.getpass('Enter your password:\n')
try:
imapSession = imaplib.IMAP4_SSL('imap.gmail.com',993)
typ, accountDetails = imapSession.login(userName, passwd)
if typ != 'OK':
print ('Not able to sign in!')
raise
imapSession.select('Inbox')
typ, data = imapSession.search(None, 'ALL')
if typ != 'OK':
print ('Error searching Inbox.')
raise
# Iterating over all emails
for msgId in data[0].split():
typ, messageParts = imapSession.fetch(msgId, '(RFC822)')
if typ != 'OK':
print ('Error fetching mail.')
raise
#print(type(emailBody))
emailBody = messageParts[0][1]
#mail = email.message_from_string(emailBody)
mail = email.message_from_bytes(emailBody)
for part in mail.walk():
#print (part)
if part.get_content_maintype() == 'multipart':
# print part.as_string()
continue
if part.get('Content-Disposition') is None:
# print part.as_string()
continue
fileName = part.get_filename()
if bool(fileName):
filePath = os.path.join(detach_dir, 'attachments', fileName)
if not os.path.isfile(filePath) :
print (fileName)
fp = open(filePath, 'wb')
fp.write(part.get_payload(decode=True))
fp.close()
imapSession.close()
imapSession.logout()
except :
print ('Not able to download all attachments.')
time.sleep(3)
質問は非常に古く、その時点でGmail APIは利用できませんでした。しかし今、GoogleはIMAPにアクセスするためのGmail APIを提供しています。 GoogleのGmail API こちら をご覧ください。 pypiの google-api-python-client も参照してください。
/*based on http://www.codejava.net/Java-ee/javamail/using-javamail-for-searching-e-mail-messages*/
package getMailsWithAtt;
import Java.io.File;
import Java.io.IOException;
import Java.text.ParseException;
import Java.text.SimpleDateFormat;
import Java.util.Date;
import Java.util.Properties;
import javax.mail.Address;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeBodyPart;
import javax.mail.search.AndTerm;
import javax.mail.search.SearchTerm;
import javax.mail.search.ReceivedDateTerm;
import javax.mail.search.ComparisonTerm;
public class EmailReader {
private String saveDirectory;
/**
* Sets the directory where attached files will be stored.
*
* @param dir
* absolute path of the directory
*/
public void setSaveDirectory(String dir) {
this.saveDirectory = dir;
}
/**
* Downloads new messages and saves attachments to disk if any.
*
* @param Host
* @param port
* @param userName
* @param password
* @throws IOException
*/
public void downloadEmailAttachments(String Host, String port,
String userName, String password, Date startDate, Date endDate) {
Properties props = System.getProperties();
props.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("imaps");
store.connect("imap.gmail.com", userName, password);
// ...
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
SearchTerm olderThan = new ReceivedDateTerm (ComparisonTerm.LT, startDate);
SearchTerm newerThan = new ReceivedDateTerm (ComparisonTerm.GT, endDate);
SearchTerm andTerm = new AndTerm(olderThan, newerThan);
//Message[] arrayMessages = inbox.getMessages(); <--get all messages
Message[] arrayMessages = inbox.search(andTerm);
for (int i = arrayMessages.length; i > 0; i--) { //from newer to older
Message msg = arrayMessages[i-1];
Address[] fromAddress = msg.getFrom();
String from = fromAddress[0].toString();
String subject = msg.getSubject();
String sentDate = msg.getSentDate().toString();
String receivedDate = msg.getReceivedDate().toString();
String contentType = msg.getContentType();
String messageContent = "";
// store attachment file name, separated by comma
String attachFiles = "";
if (contentType.contains("multipart")) {
// content may contain attachments
Multipart multiPart = (Multipart) msg.getContent();
int numberOfParts = multiPart.getCount();
for (int partCount = 0; partCount < numberOfParts; partCount++) {
MimeBodyPart part = (MimeBodyPart) multiPart
.getBodyPart(partCount);
if (Part.ATTACHMENT.equalsIgnoreCase(part
.getDisposition())) {
// this part is attachment
String fileName = part.getFileName();
attachFiles += fileName + ", ";
part.saveFile(saveDirectory + File.separator + fileName);
} else {
// this part may be the message content
messageContent = part.getContent().toString();
}
}
if (attachFiles.length() > 1) {
attachFiles = attachFiles.substring(0,
attachFiles.length() - 2);
}
} else if (contentType.contains("text/plain")
|| contentType.contains("text/html")) {
Object content = msg.getContent();
if (content != null) {
messageContent = content.toString();
}
}
// print out details of each message
System.out.println("Message #" + (i + 1) + ":");
System.out.println("\t From: " + from);
System.out.println("\t Subject: " + subject);
System.out.println("\t Received: " + sentDate);
System.out.println("\t Message: " + messageContent);
System.out.println("\t Attachments: " + attachFiles);
}
// disconnect
inbox.close(false);
store.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
System.exit(1);
} catch (MessagingException e) {
e.printStackTrace();
System.exit(2);
} catch (IOException ex) {
ex.printStackTrace();
}
}
/**
* Runs this program with Gmail POP3 server
* @throws ParseException
*/
public static void main(String[] args) throws ParseException {
String Host = "pop.gmail.com";
String port = "995";
String userName = "[email protected]";
String password = "pass";
Date startDate = new SimpleDateFormat("yyyy-MM-dd").parse("2014-06-30");
Date endDate = new SimpleDateFormat("yyyy-MM-dd").parse("2014-06-01");
String saveDirectory = "C:\\Temp";
EmailReader receiver = new EmailReader();
receiver.setSaveDirectory(saveDirectory);
receiver.downloadEmailAttachments(Host, port, userName, password,startDate,endDate);
}
}
Mavenの依存関係:
<dependency>
<groupId>com.Sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.1</version>
</dependency>
Groovy (Java Platform)の動的言語)に銀行取引明細書をダウンロードするために書いたものがあります。
import javax.mail.*
import Java.util.Properties
String gmailServer
int gmailPort
def user, password, LIMIT
def inboxFolder, root, StartDate, EndDate
// Downloads all attachments from a gmail mail box as per some criteria
// to a specific folder
// Based on code from
// http://agileice.blogspot.com/2008/10/using-groovy-to-connect-to-gmail.html
// http://stackoverflow.com/questions/155504/download-mail-attachment-with-Java
//
// Requires:
// Java mail jars in the class path (mail.jar and activation.jar)
// openssl, with gmail certificate added to Java keystore (see agileice blog)
//
// further improvement: maybe findAll could be used to filter messages
// subject could be added as another criteria
////////////////////// <CONFIGURATION> //////////////////////
// Maximm number of emails to access in case parameter range is too high
LIMIT = 10000
// gmail credentials
gmailServer = "imap.gmail.com"
gmailPort = 993
user = "[email protected]"
password = "gmailpassword"
// gmail label, or "INBOX" for inbox
inboxFolder = "finance"
// local file system where the attachment files need to be stored
root = "D:\\AttachmentStore"
// date range dd-mm-yyyy
StartDate= "31-12-2009"
EndDate = "1-6-2010"
////////////////////// </CONFIGURATION> //////////////////////
StartDate = Date.parse("dd-MM-yyyy", StartDate)
EndDate = Date.parse("dd-MM-yyyy", EndDate)
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
props.setProperty("mail.imaps.Host", gmailServer);
props.setProperty("mail.imaps.port", gmailPort.toString());
props.setProperty("mail.imaps.partialfetch", "false");
def session = javax.mail.Session.getDefaultInstance(props,null)
def store = session.getStore("imaps")
store.connect(gmailServer, user, password)
int i = 0;
def folder = store.getFolder(inboxFolder)
folder.open(Folder.READ_ONLY)
for(def msg : folder.messages) {
//if (msg.subject?.contains("bank Statement"))
println "[$i] From: ${msg.from} Subject: ${msg.subject} -- Received: ${msg.receivedDate}"
if (msg.receivedDate < StartDate || msg.receivedDate > EndDate) {
println "Ignoring due to date range"
continue
}
if (msg.content instanceof Multipart) {
Multipart mp = (Multipart)msg.content;
for (int j=0; j < mp.count; j++) {
Part part = mp.getBodyPart(j);
println " ---- ${part.fileName} ---- ${part.disposition}"
if (part.disposition?.equalsIgnoreCase(Part.ATTACHMENT)) {
if (part.content) {
def name = msg.receivedDate.format("yyyy_MM_dd") + " " + part.fileName
println "Saving file to $name"
def f = new File(root, name)
//f << part.content
try {
if (!f.exists())
f << part.content
}
catch (Exception e) {
println "*** Error *** $e"
}
}
else {
println "NO Content Found!!"
}
}
}
}
if (i++ > LIMIT)
break;
}
Gmailは標準プロトコルのPOPおよびIMAPをサポートしているため、いずれかのプロトコルのクライアント側を提供するプラットフォーム、ツール、アプリケーション、コンポーネント、またはAPIはすべて動作するはずです。
お気に入りの言語/プラットフォーム(例:「python」)に加えて「pop」、「imap」、「open source」、「download」または「review」でGoogle検索を実行することをお勧めします。オプションを取得します。
無料のアプリケーションやコンポーネントは多数あります。価値があると思われるものをいくつか選び、レビューを確認してからダウンロードしてお楽しみください。
GMailに接続するにはSSLが必要であることを知っておく必要があります(POP3とIMAPの両方-これはもちろん、ポート25以外のSMTPサーバーにも当てはまりますが、それは別の話です)。
Javaの場合、 G4J が使用されます。 Java(ホームページのスクリーンショットは、これを中心に構築されたデモ用の電子メールクライアントです)を介してGoogle Mailと通信するためのAPIセットです。
ウィキペディアの GMailサードパーティアドオン をご覧になりましたか?
特に、 PhpGmailDrive は、そのまま使用することも、インスピレーションを調べることもできるオープンソースのアドオンですか?