Skip to content

Latest commit

 

History

History
294 lines (237 loc) · 9.13 KB

220224.md

File metadata and controls

294 lines (237 loc) · 9.13 KB

Day 132

업무자동화(RPA)

웹 자동화

Handle

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
s = Service('C:/webdriver/chromedriver.exe')

browser = webdriver.Chrome(service=s, options=options)
browser.get('https://www.w3schools.com/tags/att_input_type_radio.asp')
curr_handle = browser.current_window_handle # 현재 윈도우 핸들 정보
print(curr_handle)

# Try it Yourself 버튼 클릭해서 새 탭 열림
browser.find_element(By.XPATH, '//*[@id="main"]/div[2]/a').click()

handles = browser.window_handles # 모든 핸들 정보
for handle in handles:
    print(handle) # 각 핸들 정보
    browser.switch_to.window(handle) # 각 핸들로 이동
    print(browser.title) # 현재 핸들(브라우저)의 제목 표시
    print()

# 작업 중인 브라우저를 종료
print('Close current handle')
browser.close()

# 이전 핸들로 돌아오기
print('Back to first handle')
browser.switch_to.window(curr_handle)

print(browser.title)

# 브라우저 컨트롤이 가능한지 확인
print('Browser control test')
browser.get('https://naver.com')

time.sleep(3)
browser.quit()

브라우저 정보1
브라우저 정보1
HTML input type="radio"

브라우저 정보2
Tryit Editor v3.7

Close current handle
Back to first handle
HTML input type="radio"
Browser control test\

탭을 핸들로 관리를 하는 것이다.

퀴즈

자동화 요소

  1. https://www.w3schools.com 접속
  2. 화면 중간 LEARN HTML 클릭
  3. 상단 메뉴 중 HOW TO 클릭
  4. 좌측 메뉴 중 Contact Form 메뉴 클릭
  5. 입력란에 아래 값 입력
    • First Name : Kr
    • Last Name : Teaparty
    • Country : Korea
    • Subject : 퀴즈 완료
  6. 5초 대기 후 Submit 버튼 클릭
  7. 5초 대기 후 브라우저 종료
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
s = Service('C:/webdriver/chromedriver.exe')

browser = webdriver.Chrome(service=s, options=options)
# 1
browser.get('https://www.w3schools.com/default.asp')

# 2
browser.find_element(By.XPATH, '//*[@id="main"]/div[2]/div/div[1]/a[1]').click()

# 3
browser.find_element(By.LINK_TEXT, 'HOW TO').click()

# 4
browser.find_element(By.LINK_TEXT, 'Contact Form').click()

# 5
first_name = 'Kr'
last_name = 'Teaparty'
country = 'Canada'
subject = '퀴즈 완료'

browser.find_element(By.ID, 'fname').send_keys(first_name)
browser.find_element(By.ID, 'lname').send_keys(last_name)
browser.find_element(By.XPATH, f'//*[@id="country"]/option[text()="{country}"]').click()
browser.find_element(By.XPATH, '//*[@id="main"]/div[3]/textarea').send_keys(subject)

# 6
time.sleep(5)
browser.find_element(By.XPATH, '//*[@id="main"]/div[3]/a').click()

# 7
time.sleep(5)
browser.quit()

이메일 자동화

메일 발신 기본

# account.py
EMAIL_ADDRESS = "Example1@gmail.com" # 이메일 주소
EMAIL_PASSWORD = "password"        # 앱 비밀번호
import smtplib
from account import *

with smtplib.SMTP("smtp.gmail.com", 587) as smtp:
    smtp.ehlo()     # 연결이 잘 수립되는지 확인
    smtp.starttls() # 모든 내용이 암호화되어 전송
    smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD) # 로그인

    subject = "test mail"  # 메일 제목
    body = "mail body"     # 메일 본문

    msg = f"Subject: {subject}\n{body}"
    
    # 발신자, 수신자, 정해진 형식의 메세지
    smtp.sendmail(EMAIL_ADDRESS, EMAIL_ADDRESS, msg)

한글로 내용을 입력하면 인코딩 오류가 발생한다.

메일 발신 고급

import smtplib
from account import *
from email.message import EmailMessage

msg = EmailMessage()
msg["Subject"] = "테스트 메일"   # 제목
msg["From"] = EMAIL_ADDRESS     # 보내는 사람
msg["To"] = EMAIL_ADDRESS       # 받는 사람

# 여러 명에게 메일을 보낼 때
# 방법 1
msg["To"] = "Email1@gmail.com, Email2@gmail.com"

# 방법 2
to_list = ["Email1@gmail.com", "Email2@gmail.com"]
msg["To"] = ", ".join(to_list)

# 참조
msg["Cc"] = "Email1@gmail.com"

# 비밀참조
msg["Bcc"] = "Email1@gmail.com"

msg.set_content("테스트 본문")   # 본문

with smtplib.SMTP("smtp.gmail.com", 587) as smtp:
    smtp.ehlo()
    smtp.starttls()
    smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
    smtp.send_message(msg)

join을 하게되면 list의 각 요소들을 앞의 문자열로 연결한다. 위의 예에서는 다음과 같은 결과가 나온다.

Email1@gmail.com, Email2@gmail.com

이렇게 EmailMessage 객체를 사용하면 한글로도 보낼 수 있고 알기 쉬워진다.

파일 첨부

import smtplib
from account import *
from email.message import EmailMessage

msg = EmailMessage()
msg["Subject"] = "테스트 메일"   # 제목
msg["From"] = EMAIL_ADDRESS     # 보내는 사람
msg["To"] = EMAIL_ADDRESS       # 받는 사람
msg.set_content("다운로드 하세요")

# MIME-Type에 맞춰서 maintype과 subtype을 입력해줘야 한다.
with open("./excel_automation/aurora.jpg", "rb") as f:
    msg.add_attachment(f.read(), maintype="image", subtype="jpg", filename=f.name)

with smtplib.SMTP("smtp.gmail.com", 587) as smtp:
    smtp.ehlo()
    smtp.starttls()
    smtp.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
    smtp.send_message(msg)

MIME-Type은 링크를 참조하면 된다.

메일 수신

from imap_tools import MailBox
from account import *

mailbox = MailBox("imap.gmail.com", 993)
mailbox.login(EMAIL_ADDRESS, EMAIL_PASSWORD, initial_folder="INBOX")

# limit : 최대 메일 갯수
# reverse : True는 최근 메일부터, False는 과거 메일부터
for msg in mailbox.fetch(limit=1, reverse=True):
    print("제목", msg.subject)
    print("발신자", msg.from_)
    print("수신자", msg.to)
    print("참조자", msg.cc)
    print("비밀참조자", msg.bcc)
    print("날짜", msg.date)
    print("본문", msg.text)
    print("HTML 메세지", msg.html)
    print("=" * 15)

    # 첨부 파일
    for att in msg.attachments:
        print("첨부파일 이름", att.filename)
        print("타입", att.content_type)
        print("크기", att.size)

        # 파일 다운
        with open("download_" + att.filename, "wb") as f: # "download_파일명"으로 다운로드
            f.write(att.payload)
            print("첨부 파일 {} 다운로드 완료".format(att.filename))

mailbox.logout()

limit 옵션은 받아올 최대 메일 수, reverse 옵션은 True면 최신 것부터, False면 예전 것부터 받아온다.

메일 검색

from imap_tools import MailBox
from account import *

# with를 사용하면 mailbox.logout()을 마지막에 사용하지 않아도 된다.
with MailBox("imap.gmail.com", 993).login(EMAIL_ADDRESS, EMAIL_PASSWORD, initial_folder="INBOX") as mailbox:
    # 전체 메일 다 가져오기
    for msg in mailbox.fetch():
        print("[{}] {}".format(msg.from_, msg.subject)) # [발신자] 제목
    
    # 읽지 않은 메일 가져오기
    for msg in mailbox.fetch('(UNSEEN)'):
        print("[{}] {}".format(msg.from_, msg.subject))

    # 특정인이 보낸 메일 가져오기
    for msg in mailbox.fetch('(FROM Email1@gmail.com)'):
        print("[{}] {}".format(msg.from_, msg.subject))
    
    # 어떤 글자를 포함하는 메일 (제목, 본문)
    # 작은 따옴표로 먼저 감싸고 실제 text부분을 큰 따옴표로 감싸줘야 한다.
    # 띄어쓰기로 구분해서 아래와 같이 적으면 "test", "mail" 각각의 단어를 포함하는 메일을 찾는다.
    for msg in mailbox.fetch('(TEXT "test mail")'):
        print("[{}] {}".format(msg.from_, msg.subject))

    # 어떤 글자를 포함하는 메일 (제목만)
    # 한글 텍스트로 검색하면 에러가 발생한다.
    for msg in mailbox.fetch('(SUBJECT "test mail")'):
        print("[{}] {}".format(msg.from_, msg.subject))

    # 어떤 글자(한글)을 포함하는 메일 필터링(제목만)
    for msg in mailbox.fetch(limit=5, reverse=True):
        if "테스트" in msg.subject:
            print("[{}] {}".format(msg.from_, msg.subject))

    # 특정 날짜 이후의 메일 필터링
    for msg in mailbox.fetch('(SENTSINCE 07-NOV-2020)'):
        print("[{}] {}".format(msg.from_, msg.subject))

    # 특정 날짜에 온 메일
    # 날짜 형식을 맞춰줘야 하므로 계산이 필요하면 time과 datetime 모듈을 사용하면 된다.
    for msg in mailbox.fetch('(ON 07-NOV-2020)'):
        print("[{}] {}".format(msg.from_, msg.subject))

    # 2가지 이상의 조건을 모두 만족하는 메일
    for msg in mailbox.fetch('(ON 07-NOV-2020 SUBJECT "test mail")'):
        print("[{}] {}".format(msg.from_, msg.subject))

    # 2가지 조건 중 하나라도 만족하는 메일
    for msg in mailbox.fetch('(OR ON 07-NOV-2020 SUBJECT "test mail")'):
        print("[{}] {}".format(msg.from_, msg.subject))