자동화
Python 기본 문법 및 개념
파일 실행
1
__name__ == "__main__"
해당 파이썬 파일이 직접 실행될 때만 그 안의 코드를 실행하도록 하는 구문
다른 파일에서 import할 경우에는 실행되지 않는다.
Import
다른 파일에서 실행할 때 import 구문으로 가져오기 위해 파일명을 간단하게 작성
1
2
3
4
5
6
7
8
# a.py
def hello_word() :
print("wow")
# b.py
import a
x = a.hello_world()
# wow 출력
in, not in
1
2
3
4
5
6
x = "hello world"
y = "hello world _ with python"
if x in y :
print("wow")
# wow
문자열 포함 여부 확인
리스트, 튜플, 딕셔너리에서도 활용 가능
문자열 가공
1
df['ROAS'] = ((df['매출'] / df['광고비']) * 100).round(0).astype(int).astype(str) + "%"
(계산) → 숫자 Series
.astype(str)
→ 각 값이 문자열로 변환”%” → 퍼센트 기호 붙이기
*결측치가 없다면 astype()
으로 한번에 변환.
변환할 수 없는 데이터가 포함된다면 pd.to_numeric()
으로 처리
날짜 설정
datetime.timedelta는 시간 간격을 나타내는 객체로 날짜나 시간에 특정 기간을 더하거나 뺄 때 사용한다.
n일 전의 날짜를 구하려면 뺄셈, n일 후의 날짜를 구하려면 덧셈을 하면 된다.
1
2
3
4
5
6
7
from datetime import datetime, timedelta
today = datetime.date.today()
x = timedelta(days=365)
print(today + x)
print(today - x)
# 2026-09-19
# 2024-09-19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from datetime import datetime, timedelta
#### 오늘 ~ 2주 전
today = datetime.today()
two_weeks_ago = today - timedelta(weeks=2)
target_date = two_weeks_ago + timedelta(days=1)
formatted = target_date.strftime("%Y-%m-%d")
#### 전날 ~ 2주
today = datetime.today()
yesterday = today - timedelta(days=1)
two_weeks_ago = yesterday - timedelta(weeks=2)
formatted = two_weeks_ago.strftime("%Y-%m-%d")
print(formatted)
Win32com
Microsoft에서 제공하는 윈도우 프로그램을 파이썬으로 제어할 수 있도록 만든 API
Microsoft Excel, Power point, Word, Outlook 등 제어 가능
1
pip install pywin32
1
2
3
import win32com.client as py
outlook = py.Dispatch("Outlook.Application").GetNamespace("MAPI")
outlook.GetDefaultFolder(6) # 받은 편지함
실행
5초마다 확인하고 최대 90초까지 대기
최신순 정렬 후 보낸 사람이 TARGET_SENDER와 일치하는 메일을 탐색
현재 시간 기준 5분 이내 메일이라면 본문 2번째 줄을 출력 ```py def email_code(): TARGET_SENDER = “EXCEL” WAIT_TIMEOUT = 90 CHECK_INTERVAL = 5
outlook = py.Dispatch(“Outlook.Application”).GetNamespace(“MAPI”) inbox = outlook.GetDefaultFolder(6)
start_time = time.time() while time.time() - start_time <= WAIT_TIMEOUT: try: messages = inbox.Items # 받은 편지함 - 모든 메시지 받기 messages.Sort(“[ReceivedTime]”, True) # 최신순 정렬 latest_mail = messages.GetFirst() # 최신 메일 하나만 가져오기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
if latest_mail and TARGET_SENDER in latest_mail.SenderName: # 발신인 now = datetime.now() mail_time = latest_mail.ReceivedTime.replace(tzinfo=None) if (mail_time.date() == now.date()) and (abs((now - mail_time).total_seconds()) <= 300): body_lines = latest_mail.Body.splitlines() if len(body_lines) > 1: return body_lines[1] else: print("본문 줄 수 부족") return None else: print("대기 중") except Exception as e: print("오류:", e) time.sleep(CHECK_INTERVAL) print("시간 초과") return None
print(email_code())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<br><br><br>
## Excel 자동화
### 데이터 삭제
```py
import pandas as pd
from openpyxl import load_workbook
new_path = 'new/' # 새로 추가할 엑셀 파일 위치
old_path = 'old/' # 붙여넣을 엑셀 파일 위치
# header → index 기준
df1 = pd.read_excel(new_path + 'new_apple.xlsx', sheet_name='apple', header=1)
print(df1.shape)
df2 = pd.read_excel(new_path + 'new_mango.xlsx', sheet_name='mango', header=2)
print(df2.shape)
wb = load_workbook(old_path + 'fruit.xlsx')
# excel은 1번부터
ws = wb['apple']
for row_idx in range(ws.max_row, df1.shape[0]+3, -1): # 4번째 행~
ws.delete_rows(row_idx)
wb.save("fruit.xlsx")
wb = load_workbook('fruit.xlsx')
ws = wb['mango']
for row_idx in range(ws.max_row, df2.shape[0]+2, -1): # 3번째 행 ~
ws.delete_rows(row_idx)
wb.save("fruit.xlsx")
새 데이터가 500행이고 기존 데이터가 600행이라면 → 남은 100행은 제거
데이터 붙여넣기
이해하기 쉽게 시트명을 변경해봤다.(위와 동일x)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from openpyxl import load_workbook
path = 'new/' # apple과 mango의 파일 위치
a = 'new_apple.xlsx'
b = 'new_mango.xlsx'
c = 'fruit.xlsx' # 복붙할 xlsx
a_wb = load_workbook(path + a, data_only = True) # 수식x. 값만 가져오기
a_ws = a_wb['apple']
# 행의 개수 만큼 튜플 반환
data_to_copy = []
for row in a_ws.iter_rows(min_row=4, max_row=a_ws.max_row, values_only=True):
data_to_copy.append(row)
b_wb = load_workbook(c)
b_ws = b_wb['old_apple'] # 저장할 시트 명
# excel은 1부터 시작 → start=4, start=1
for row_idx, data_row in enumerate(data_to_copy, start=4):
for col_idx, value in enumerate(data_row, start=1):
b_ws.cell(row=row_idx, column=col_idx, value=value)
b_wb.save('new_fruit.xlsx')
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
a_wb = load_workbook(path + b, data_only = True)
a_ws = a_wb['mango']
# 행의 개수 만큼 튜플 반환
data_to_copy = []
for row in a_ws.iter_rows(min_row=4, max_row=a_ws.max_row, values_only=True):
data_to_copy.append(row)
b_wb = load_workbook('fruit.xlsx')
b_ws = b_wb['old_mango']
# excel은 1부터 시작 → start=3, start=1
for row_idx, data_row in enumerate(data_to_copy, start=3):
for col_idx, value in enumerate(data_row, start=1):
b_ws.cell(row=row_idx, column=col_idx, value=value)
b_wb.save('new_fruit.xlsx')
DataFrame
1
2
df_platforms = pd.DataFrame.from_dict(df["플랫폼별"], orient="index").reset_index()
df_platforms = df_platforms.rename(columns={"index": "플랫폼"})
1
2
3
4
results = {
"NAVER": {"광고비": 1000, "매출": 3000, "노출": 5000, "유입": 200},
"GOOGLE": {"광고비": 2000, "매출": 6000, "노출": 8000, "유입": 350}
}
1
pd.DataFrame.from_dict(results, orient="index")
바깥 딕셔너리의 key 를 DataFrame의 index 로 사용
. | 광고비 | 매출 | 노출 | 유입 |
---|---|---|---|---|
NAVER | 1000 | 3000 | 5000 | 200 |
2000 | 6000 | 8000 | 350 |
1
.reset_index()
Index를 컬럼으로 빼기 위해 사용
index | 광고비 | 매출 | 노출 | 유입 |
---|---|---|---|---|
NAVER | 1000 | 3000 | 5000 | 200 |
2000 | 6000 | 8000 | 350 |
1
.rename(columns={"index": "플랫폼"})
컬럼 이름 index를 플랫폼으로 변경
REFERENCE