๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป DEV/Python

[Python] Imaplib์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฉ”์ผ ์ฝ๊ณ ์“ฐ๊ธฐ

by vodkassi 2021. 6. 23.
728x90

ํ˜„์žฌ ์ˆ˜๊ฐ•ํ•˜๊ณ  ์žˆ๋Š” ์›น๊ฐœ๋ฐœ ์ฝ”์Šค์—์„œ๋Š” ํŽ˜์–ด์™€์˜ ํ˜‘์—… ๊ณผ์ œ๊ฐ€ ๋๋‚  ๋•Œ๋งˆ๋‹ค ์ƒํ˜ธํ‰๊ฐ€ ๋‚ด์šฉ์„ ์ด๋ฉ”์ผ๋กœ ๋ณด๋‚ด์ค€๋‹ค. 

์ •๋ฆฌ๋ฒฝ์ด ๋„์ ธ์„œ ํ•˜๋‚˜ํ•˜๋‚˜ ๋‹ค ๊ธ์–ด ์ •๋ฆฌํ•ด๋ณผ๊นŒ ์‹ถ์—ˆ๋Š”๋ฐ, ๋งค๋ฒˆ ๋‚ด์šฉ์„ ์ง์ ‘ ๊ธ์–ด ์™€์„œ ์ •๋ฆฌํ•˜๊ธฐ๊ฐ€ ๋ฒˆ๊ฑฐ๋กญ๊ณ , ๊ท€์ฐฎ์•˜๋‹ค.

 

โœจ โœจ ๊ทธ๋Ÿฌ๋‹ค ์™ ์ง€ ํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋งค์šฐ ๊ฐ„๋‹จํ•œ ์ž‘์—…์ด ๋  ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค. 

Python ์„ ๋Šฅ์ˆ™ํ•˜๊ฒŒ ๋‹ค๋ฃจ์ง€๋Š” ์•Š์ง€๋งŒ, ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์„ ์จ ๋ณธ๋‹ค๋ฉด ์ด ๋ชจ๋“  ๋ฆฌ๋ทฐ ๋ฉ”์ผ์„ ํ•œ ๋ฒˆ์— ๋ชจ์•„์„œ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ํ˜•ํƒœ์˜ ํŒŒ์ผ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์„ ๊ฒƒ ๊ฐ™์•˜๋‹ค. ๊ทธ๋ž˜์„œ ์•Œ์•„๋ณธ ๊ฒƒ์ด ๋ฐ”๋กœ python ์˜ imaplib ๋ชจ๋“ˆ์ด๋‹ค. 

 

 ์ด๋ฒˆ ๊ธ€์€ ๊ฐœ์ธ ์ž๋™ํ™” ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋Š”๋ฐ ๋ฐฐ์šด ๋‚ด์šฉ๊ณผ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ์ค‘์ ์œผ๋กœ ์ •๋ฆฌํ•ด๋ณธ๋‹ค. 

 

 


 

ํŒŒ์ด์ฌ์˜ ๊ฐ€์žฅ ํฐ ์žฅ์  ์ค‘ ํ•˜๋‚˜๋Š” ์†์‰ฌ์šด ๋ชจ๋“ˆ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํ™œ์šฉ์ด๋‹ค. ๋‚ด์žฅ ๋ชจ๋“ˆ์€ ๋ฌผ๋ก  pip (ํŒŒ์ด์ฌ ํŒจํ‚ค์ง€ ์„ค์น˜ ๊ด€๋ฆฌ์ž) ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ๊ทธ๋Œ€๋กœ ๋Œ์–ด์™€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

์ด๋Ÿฌํ•œ ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ ์ค‘ ์ด๋ฉ”์ผ ํ†ต์‹  ํฌํŠธ์— ์ ‘์†ํ•˜์—ฌ ํŒŒ์ด์ฌ ์ฝ”๋“œ๋กœ ์ด๋ฉ”์ผ์„ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๋ชจ๋“ˆ์ด ์žˆ๋Š”๋ฐ, ๋ฐ”๋กœ SMTPlib (๋ฉ”์ผ ๋ฐœ์‹ ) ๊ณผ IMAPlib (๋ฉ”์ผ ์ˆ˜์‹ ) ์ด๋‹ค. ์ด๋ฒˆ ๊ฒŒ์‹œ๊ธ€์—์„œ๋Š” IMAP ์˜ ์ •์˜์™€ Python ์—์„œ์˜ IMAPlib ํ™œ์šฉ๋ฒ•์„ ๊ฐ„๋‹จํžˆ ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค. ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ€ ํ†ต์‹ ์„ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด HTTP (hypertext transfer protocol) ์ด๋ผ๋ฉด, ๊ทธ๋“ค์ด ์ด๋ฉ”์ผ์„ ์ฃผ๊ณ ๋ฐ›์„ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœํ† ์ฝœ์ด ๋ฐ”๋กœ SMPT (Simple Mail Transfer Protocol) ๊ณผ IMAP (Internet Message Access Protocol) ์ด๋‹ค. 

 

SMTP ๋ž€?

์ด๋ฉ”์ผ์„ ์ „์†กํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœํ† ์ฝœ๋กœ, ํด๋ผ์ด์–ธํŠธ ๋˜๋Š” ์ธํ„ฐ๋„ท์—์„œ ์„œ๋ฒ„๋กœ ๋ฉ”์ผ์„ ์ „์†กํ•  ๋•Œ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. 

 

IMAP ๋ž€?

์ด๋ฉ”์ผ์„ ์ˆ˜์‹ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœํ† ์ฝœ๋กœ, ์„œ๋ฒ„์— ์ง์ ‘ ์ ‘์†ํ•˜์—ฌ ๋ฉ”์ผ์„ ํ™•์ธํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ๋˜ ๋‹ค๋ฅธ ์ˆ˜์‹  ํ”„๋กœํ† ์ฝœ์ธ POP3 ์™€ ๋น„๊ตํ•˜์˜€์„ ๋•Œ ์ง์ ‘ ํ™•์ธํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฉ”์ผ์„ ํด๋ฆญํ•ด์•ผ๋งŒ ๋ฉ”์ผ ๋‚ด์šฉ์„ ๋‹ค์šด๋กœ๋“œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์œผ๋‚˜, ์˜คํ”„๋ผ์ธ ์ƒํƒœ์—์„œ๋Š” ํ™•์ธํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์ ๊ณผ ๋‹ค์†Œ ๋งŽ์€ ์šฉ๋Ÿ‰์„ ์ฐจ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹จ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. 

 

 

SMTP ์™€ IMAP ์˜ ํ†ต์‹  ์ ˆ์ฐจ์ด๋‹ค.

 

Python ์˜ Imaplib

Python ์—์„œ IMAP ์„œ๋ฒ„์— ์ ‘์†ํ•˜์—ฌ ์ด๋ฉ”์ผ์„ ์ฝ๊ณ ์ž ํ•œ๋‹ค๋ฉด ์šฐ์„  imaplib ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํŒŒ์ด์ฌ ํŒŒ์ผ ์ƒ๋‹จ์— 

 

import imaplib

 

๋ฅผ ์‹คํ–‰ํ•ด์ค€๋‹ค. 

 

์ดํ›„ ์ ‘์†ํ•˜๊ณ ์ž ํ•˜๋Š” IMAP ์„œ๋ฒ„๋ฅผ ์ง€์ •ํ•ด์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋Š” ์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ์ƒ๊ฐํ•˜๋Š” ์ด๋ฉ”์ผ ๋กœ๊ทธ์ธ ๊ณผ์ •๊ณผ ๋™์ผํ•˜๋‹ค. ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณ€์ˆ˜๋กœ ์ƒ์„ฑํ•˜์—ฌ ์ž…๋ ฅํ•ด์ฃผ๋ฉด ๋ชฉํ‘œ์ ์— ์ ‘์†ํ•˜๊ฒŒ ๋œ๋‹ค.

 

user = 'something@gmail.com'
password = 'asdfasdfasdfasdf'

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

 

์œ„์—์„œ ์ฃผ์˜ํ•  ์ ์€ gmail ์„œ๋ฒ„์— ์ ‘์†ํ•  ๊ฒฝ์šฐ, 2๋‹จ๊ณ„ ๋ณด์•ˆ ์ธ์ฆ์„ ๊ฑฐ์ณ ์ƒ์„ฑํ•œ 16์ž๋ฆฌ ์•ฑ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. gmail ์€ ๋ณด์•ˆ ๋ฌธ์ œ๋กœ, ์œ ์ €๊ฐ€ ์‚ฌ์ „์— ๋“ฑ๋กํ•œ ๊ธฐ๊ธฐ ์ด์™ธ์˜ ๋‹ค๋ฅธ ๊ธฐ๊ธฐ์—์„œ ์ ‘์†ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ ์ถ”๊ฐ€ ์ธ์ฆ ์ ˆ์ฐจ๋ฅผ ๋ฐŸ๊ฒŒ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๋‹น ์ ˆ์ฐจ๊ฐ€ ๊นŒ๋‹ค๋กญ๊ธฐ๋„ ํ•  ๋ฟ๋”๋Ÿฌ ๋ฐ˜๋ณต์ ์œผ๋กœ ํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๊ฒฝ์šฐ ๋งค๋ฒˆ ์ƒˆ๋กœ์šด ๋กœ๊ทธ์ธ ์ •๋ณด๋กœ ์ธ์‹๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋น„์ •์ƒ์ ์ธ ์ ‘์†์œผ๋กœ ๊ฐ„์ฃผ๋˜์–ด ์„œ๋ฒ„๊ฐ€ ๋‹ซํž ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์œ ์ €๊ฐ€ ์ƒˆ๋กœ์šด ์•ฑ์—์„œ๋„ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์•ฑ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™œ์šฉํ•˜๋ฉด, ํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด์„œ๋„ ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. 

 

์ดํ›„ ์ด๋ฉ”์ผ์„ ๋ถˆ๋Ÿฌ๋“ค์ด๊ณ ์ž ํ•˜๋Š” ๋ฉ”์ผํ•จ์„ ์„ ํƒํ•ด์ฃผ๋ฉด ๋˜๋Š”๋ฐ, ๋ฉ”์ผํ•จ ๋ชฉ๋ก์€ imap ๊ณต์‹๋ฌธ์„œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

imap.select("INBOX")

 

 

๋ฉ”์ผํ•จ๊นŒ์ง€ ์„ ํƒํ•ด ์ฃผ์—ˆ๋‹ค๋ฉด ์›ํ•˜๋Š” ์กฐ๊ฑด์„ ์„ ํƒํ•˜์—ฌ ์ฝ๊ณ ์ž ํ•˜๋Š” ๋ฉ”์ผ์„ ํ•„ํ„ฐ๋งํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ๋ฉ”์ผ์—๋Š” ๊ณ ์œ ํ•œ uid ๊ฐ€ ๋ถ€์—ฌ๋˜๋Š”๋ฐ, ์„ ํƒํ•œ ๋ฉ”์ผ์˜ uid ๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

 

status, messages = imap.uid('search', None, '(FROM "somewhere@naver.com")')
messages = messages[0].split()

 

์œ„์˜ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ, ('OK', [b'00001 00002 .....']) ๋“ฑ๊ณผ ๊ฐ™์€ tuple ๊ฐ์ฒด๊ฐ€ ๋ฐ˜ํ™˜๋˜๋ฉฐ, ๋‘ ๋ฒˆ์งธ ๋ฐ˜ํ™˜ ์ธ์ž์ธ ๋ฐฐ์—ด์„ messages ๋ณ€์ˆ˜์— ๋‹ด์•„ ๋‹ค์‹œ ํ•œ ๋ฒˆ ๊ฐœ๋ณ„ uid ์˜ ์ง‘ํ•ฉ์ธ ๋ฐฐ์—ด๋กœ ๋‚˜๋ˆ„์–ด ์ฃผ์—ˆ๋‹ค. 

 

์ดํ›„ ์›ํ•˜๋Š” ๋ฉ”์ผ์˜ uid ๋ฅผ ์„ ํƒํ•˜์—ฌ ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋œ๋‹ค. ์ด ๋•Œ uid ์•ˆ์— ๋“ค์–ด๊ฐ€๋Š” ๋‚ด์šฉ์€ recent ๋ง๊ณ ๋Š” ๊ณ ์ •๋œ ๊ฐ’์ด๋‹ค (์ธ์ฝ”๋”ฉ ๊ด€๋ จ). 

 

recent = messages[-1]
res, msg = imap.uid('fetch', recent, "(RFC822)")

 

์—ฌ๊ธฐ๊นŒ์ง€ ์‹คํ–‰ํ•œ ๋’ค print ๋ฌธ์œผ๋กœ msg ๋ฅผ ์ถœ๋ ฅํ•ด๋ณด๋ฉด ๋ฉ”์ผ์˜ ํ—ค๋”๋ถ€ํ„ฐ ๋ณธ๋ฌธ์ด ํŒŒ์‹ฑ๋˜๊ธฐ ์ด์ „ ์ƒํƒœ๋กœ ์ญ‰ ํŽผ์ณ์งˆ ๊ฒƒ์ด๋‹ค. 

๋Œ€๋žต ์ด๋Ÿฐ ๋Š๋‚Œ

์•„์ง ์ •์ œ๋˜์ง€ ์•Š์€ ๋ฉ”์ผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•ด์ฃผ๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ถ”๊ฐ€ ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค. 

์ง์ ‘ ๋ˆˆ์œผ๋กœ ํ™•์ธํ•˜๊ธฐ๋Š” ์–ด๋ ต์ง€๋งŒ ์œ„์— ํ‘œ์‹œ๋œ ๋ฉ”์ผ ์ •๋ณด๋Š” ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ์ €์žฅ๋˜์–ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฉ”์ผ ํ™•์ธ์„ ์œ„ํ•ด ํ•„์š”ํ•œ ์ •๋ณด๋งŒ์„ ๋”ฐ๋กœ ์ถ”์ถœํ•œ ๋’ค, ํ•ด๋‹น ๋‚ด์šฉ์„ ๋””์ฝ”๋”ฉํ•ด์•ผ ํ•œ๋‹ค. 

 

raw = msg[0][1].decode('utf-8')

 

๋””์ฝ”๋”ฉ ํ•จ์ˆ˜ ๋‚ด๋ถ€์— 'utf-8'์„ ์‚ฌ์šฉํ•ด์คŒ์œผ๋กœ์จ ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์บ๋ฆญํ„ฐ๋กœ ๋ณ€ํ™˜์„ ํ•ด์ฃผ๊ฒŒ ๋œ๋‹ค. 

 

์ด์ œ ์ƒˆ๋กœ์šด ๋ชจ๋“ˆ์„ ํ™œ์šฉํ•  ๋•Œ๊ฐ€ ๋˜์—ˆ๋Š”๋ฐ, ํŒŒ์ด์ฌ์— ๋‚ด์žฅ๋˜์–ด ์žˆ๋Š” email ๋ชจ๋“ˆ์ด๋‹ค. ํ•ด๋‹น ๋ชจ๋“ˆ์€ ํŒŒ์ด์ฌ์—์„œ email ๊ฐ์ฒด๋ฅผ ์ž์œ ์ž์žฌ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ๋„์™€์ค€๋‹ค. ์•ž์„œ ๋””์ฝ”๋”ฉํ•œ ๋‚ด์šฉ์ด ์ด์ œ ์˜์–ด ๋˜๋Š” ํ•œ๊ตญ์–ด๋กœ ๋ณ€ํ™˜๋˜๊ธฐ๋Š” ํ–ˆ์ง€๋งŒ ์ด๋ฉ”์ผ์˜ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณธ๋ฌธ๋งŒ, ๋˜๋Š” ์ˆ˜์‹ ์ธ/๋ฐœ์‹ ์ธ๋งŒ ๋”ฐ๋กœ ์ถ”์ถœํ•ด๋ณด๊ธฐ ์–ด๋ ค์šด ์ƒํƒœ์ด๋‹ค. ์ด๋ฅผ ์ˆ˜์›”ํ•˜๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ํ•  ๊ฒƒ์ด๋‹ค. 

 

import email

email_message = email.message_from_string(raw)

 

email_message ๋Š” email ๊ฐ์ฒด์ด๋ฉฐ, ์ด์ œ email ๊ฐ์ฒด์— ์ €์žฅ๋œ ๊ฐ’์˜ ํ‚ค๋ฅผ ํ†ตํ•ด ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋ณธ๋ฌธ, ๋ณธ๋ฌธ ํƒ€์ž…, ํ—ค๋” ๋“ฑ ์—ฌ๋Ÿฌ ์š”์†Œ๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

email_message['To'] // ์ˆ˜์‹ ์ธ
email_message['From'] // ๋ฐœ์‹ ์ธ
email_message['Subject'] // ์ œ๋ชฉ

body = email_message.get_payload(decode=True).decode()

 

์œ„์™€ ๊ฐ™์ด imaplib ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ, ์ด๋ฉ”์ผ์„ ์ฝ์–ด์ฃผ๋Š” ๊ฐ„๋‹จํ•œ ํŒŒ์ด์ฌ ์ฝ”๋“œ ์ž‘์„ฑ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 


์™„์„ฑ๋ณธ

python ์˜ imaplib ์„ ์ฐพ์•„๋ณด๊ฒŒ ๋œ ๊ณ„๊ธฐ๋Š” ์ž๋™ํ™”์— ๋Œ€ํ•œ ์š•์‹ฌ๊ณผ ๋ฐ˜๋ณต์ž‘์—…์˜ ๋น„ํšจ์œจ์„ฑ์— ๋Œ€ํ•œ ๊ท€์ฐฎ์Œ์ด์—ˆ๋‹ค.  ๋ชฉํ‘œํ•œ ์ž‘์—…์€ ํŽ˜์–ด ํ‰๊ฐ€ (๋ฆฌ๋ทฐ) ๋ฉ”์ผ์„ ์ „๋ถ€ ๊ธ์–ด์™€, ๋ณด๊ธฐ ์ข‹์€ ํ˜•ํƒœ๋กœ ์ •์ œํ•˜๊ณ , ํ•œ ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ๋„๋ก csv ํŒŒ์ผ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

 

์ด๋ฅผ ์œ„ํ•ด re (์ •๊ทœํ‘œํ˜„์‹ ํ™œ์šฉ ๋ชจ๋“ˆ), csv (csv ํŒŒ์ผ ํ™œ์šฉ ๋ชจ๋“ˆ), os (์šด์˜์ฒด์ œ ํ™œ์šฉ ๋ชจ๋“ˆ), dotenv (ํ™˜๊ฒฝ๋ณ€์ˆ˜ ํ™œ์šฉ ๋ชจ๋“ˆ) ๋“ฑ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํ•„์š”ํ•œ ๋ชจ๋“ˆ์„ ์ถ”๊ฐ€๋กœ ์„ค์น˜ํ•œ ๋’ค, ์šฉ๋„์— ๋งž๊ฒŒ ํ•„์š”ํ•œ ๋ฉ”์ผ์„ csv ํŒŒ์ผ์— ์ €์žฅํ•ด์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์™„์„ฑํ–ˆ๋‹ค. ๋˜ํ•œ ์œ„์˜ ์˜ˆ์ œ๋งŒ์œผ๋กœ๋Š” ํ•œ๊ตญ์–ด๋ฅผ ํŒŒ์‹ฑํ•˜๋Š” ๋ฐ ๋ถˆ์ถฉ๋ถ„ํ•˜์—ฌ ํ•œ๊ตญ์–ด ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ์ถ”๊ฐ€์ ์ธ ์ž‘์—…์„ ์‹คํ–‰ํ–ˆ๋‹ค.

 

from email.header import decode_header
from datetime import datetime
import imaplib, re, csv, email
import os
from dotenv import load_dotenv

# ์ €์žฅํ•  csv ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ
f = open('pair_feedback.csv', 'w', newline='')
write = csv.writer(f)
write.writerow(['#', '๋‚ ์งœ', 'ํŽ˜์–ด', '์Šคํ”„๋ฆฐํŠธ', '์ž˜ํ•œ ์ ', '๊ฐœ์„ ํ•  ์ '])

# ์œ ์ € ๊ฐœ์ธ์ •๋ณด (ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •)
load_dotenv()
user = os.environ.get('mail')  # ์ด๋ฉ”์ผ ์ฃผ์†Œ (ex. abcde@gmail.com)
password = os.environ.get('password')  # ์•ฑ ๋น„๋ฐ€๋ฒˆํ˜ธ (16์ž๋ฆฌ)

# IMAP ์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•˜๊ธฐ
imap = imaplib.IMAP4_SSL("imap.gmail.com")
imap.login(user, password)

# ์ ‘๊ทผํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฉ”์ผํ•จ ์ด๋ฆ„
imap.select("INBOX")

# status = ์ด๋ฉ”์ผ ์ ‘๊ทผ ์ƒํƒœ
# messages = ์„ ํƒํ•œ ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š” ๋ฉ”์ผ์˜ id ๋ชฉ๋ก
# ('OK', [b'00001 00002 .....'])
status, messages = imap.uid('search', None, '(FROM "notifications@typeform.com")')
messages = messages[0].split()

# ๊ฐ ๋ฉ”์ผ์— ๋Œ€ํ•˜์—ฌ ์‹คํ–‰
for n, message in enumerate(messages):

    print(f"Writing email #{n} on file...")
	
    # Standard format for fetching email message
    res, msg = imap.uid('fetch', message, "(RFC822)")  
    raw = msg[0][1]
    # type(email_message) == <class 'email.message.Message'>
    email_message = email.message_from_bytes(raw)  

    # decode 'subject' info (๋ฉ”์ผ ์ œ๋ชฉ)
    subject, encoding = decode_header(email_message["Subject"])[0]
    subject = subject.decode(encoding)  # ํ•œ๊ตญ์–ด๋กœ ๋””์ฝ”๋”ฉํ•˜๋Š” ์ž‘์—…

    if 'Pair Review' in subject:

        # decode 'date' (๋‚ ์งœ) & format
        # date = 'Thu, 08 Apr 2021 05:10:04 +0000'
        temp, _ = decode_header(email_message.get("Date"))[0]  

        temp = datetime.strptime(temp, '%a, %d %b %Y %H:%M:%S %z')
        date = temp.strftime('%Y๋…„ %m์›” %d์ผ')

        # subject ์—์„œ ํŽ˜์–ด ์ด๋ฆ„ ์ถ”์ถœ
        match = re.search(r'[๊ฐ€-ํžฃ]+๋‹˜์˜', subject)  # 'ใ…‡ใ…‡ใ…‡๋‹˜์˜' ๋ฌธ์ž์—ด ์ถ”์ถœ
        pair = match.group()  # ๋งค์น˜๋œ ๋ฌธ์ž์—ด ๋ฐ›์•„์„œ pair ๋ณ€์ˆ˜์— ํ• ๋‹น
        pair = pair[:-2]   # ์ด๋ฆ„๋งŒ ๋‚จ๋„๋ก ์Šฌ๋ผ์ด์‹ฑ

        # get mail body (๋ฉ”์ผ ๋ณธ๋ฌธ)
        # email_message.get_content_type() == 'text/html'
        body = email_message.get_payload(decode=True).decode()
        body = body[:body.rindex('<br/>')].replace('<br/>', ' ') 
        # ๋ณธ๋ฌธ (body) ์˜ ์‹œ์ž‘์ ๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ <br/> ์ด ๋“ฑ์žฅํ•˜๋Š” ์ง€์ ๊นŒ์ง€ ์ถ”์ถœ ํ›„, ๋ชจ๋“  <br/> ์„ ๊ณต๋ฐฑ์œผ๋กœ ๋Œ€์ฒด

        # body ์—์„œ Sprint ๋‚ด์šฉ ์ถ”์ถœ
        match = re.search(r'\[[\D]+\]', body) 
      	# ๋Œ€๊ด„ํ˜ธ ์•ˆ์ด Whitespace ๊ฐ€ ์•„๋‹Œ ๊ฐ’ (์˜ˆ : '[JS/Node]') ์ฐพ๊ธฐ
        sprint = match.group()  # ๋งค์น˜๋œ ๋ฌธ์ž์—ด ๋ฐ›์•„์„œ sprint ๋ณ€์ˆ˜์— ํ• ๋‹น

        # body ์—์„œ ์ž˜ํ•œ ์ , ๊ฐœ์„ ํ•  ์  ๋‚ด์šฉ ์ถ”์ถœ
        # ํ•œ๊ธ€ ์ด๋ฆ„ + ๊ธฐ์กด ๋ฌธ์žฅ ๋‚ด์šฉ (์˜ˆ : '๊น€์ฝ”๋”ฉ๋‹˜์ด ํ‰๊ฐ€ํ•œ ๋ฐ•ํ•ด์ปค๋‹˜์˜ ์ž˜ํ•œ ์ :')
        match = re.search(r'[๊ฐ€-ํžฃ]+๋‹˜์ด\sํ‰๊ฐ€ํ•œ\s[๊ฐ€-ํžฃ]+๋‹˜์˜\s์ž˜ํ•œ\s์ :', body) 
        # '...์ž˜ํ•œ ์ :' ๋ฌธ์ž์—ด์˜ ์‹œ์ž‘๊ณผ ๋ ์ธ๋ฑ์Šค ์ถ”์ถœ
        start_awesome, end_awesome = match.span()
        
        # ํ•œ๊ธ€ ์ด๋ฆ„ + ๊ธฐ์กด ๋ฌธ์žฅ ๋‚ด์šฉ (์˜ˆ : '๊น€์ฝ”๋”ฉ๋‹˜์ด ํ‰๊ฐ€ํ•œ ๋ฐ•ํ•ด์ปค๋‹˜์˜ ๊ฐœ์„ ํ•˜๋ฉด ์ข‹์„ ์ :')
        match = re.search(r'[๊ฐ€-ํžฃ]+๋‹˜์ด\s์ƒ๊ฐํ•œ\s[๊ฐ€-ํžฃ]+๋‹˜์˜\s๊ฐœ์„ ํ•˜๋ฉด\s์ข‹์„\s์ :', body) 
        # '...๊ฐœ์„ ํ•˜๋ฉด ์ข‹์„ ์ :' ๋ฌธ์ž์—ด์˜ ์‹œ์ž‘๊ณผ ๋ ์ธ๋ฑ์Šค ์ถ”์ถœ
        start_improve, end_improve = match.span()

        awesome = body[end_awesome:start_improve]
        improve = body[end_improve:]

        # csv ํŒŒ์ผ์— ์ €์žฅํ•œ ๋‚ด์šฉ ์“ฐ๊ธฐ
        write.writerow([n, date, pair, sprint, awesome, improve])

print("All complete!")
f.close()
imap.close()
imap.logout()

 

๊ทธ ๊ฒฐ๊ณผ, ๋ฉ”์ผ๋กœ ๋“ค์–ด์˜ค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด์šฉ์„ 

 

 

 

์ด๋ ‡๊ฒŒ ์ •๋ฆฌ๋œ csv ํŒŒ์ผ ํ˜•ํƒœ๋กœ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค!!

 

 

 


 

ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์˜ ์ „์ฒด ์ฝ”๋“œ์™€ ๊ตฌ์ฒด์ ์ธ README ๋Š” ์•„๋ž˜์˜ github ๋ ˆํฌ์ง€ํ† ๋ฆฌ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

https://github.com/vodkamitlime/pair_review

 

vodkamitlime/pair_review

Contribute to vodkamitlime/pair_review development by creating an account on GitHub.

github.com

 

๋‹ค์Œ ๋ชฉํ‘œ๋Š” ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ fastApi ํ”„๋ ˆ์ž„์›Œํฌ์— ์ž…ํ˜€ ์›น์—์„œ ๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋ฉ”์ผ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด csv ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฒƒ์ธ๋ฐ, ์ธ์ฆ ๋ถ€๋ถ„์„ ์•„์ง ๋ฐฐ์šฐ์ง€ ๋ชปํ•ด ์„ฑ๊ณตํ•  ์ˆ˜ ์žˆ์„์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋„์ „์€ ์–ธ์ œ๋‚˜ ์žฌ๋ฏธ์žˆ๋Š” ์ผ์ด๋‹ˆ ์กฐ๋งŒ๊ฐ„ ์‹œ๋„ํ•ด๋ณด๋ ค ํ•œ๋‹ค. 

'๐Ÿ’ป DEV > Python' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Python] sort() ํ•จ์ˆ˜์™€ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ  (0) 2020.12.22

๋Œ“๊ธ€