Python으로 카드내역 작성 자동화하기
현재 회사에서는 법인카드를 일정 금액 내에서 사용할 수 있는데, 달마다 사용내역을 제출해야 합니다.
물론 회사에 따라 카드사에서 직접 엑셀을 제공해 주기도 하지만, 지금은 그렇지 않아 수기로 작성해야 하는데 내역을 핸드폰으로 확인해 일일이 엑셀에 옮겨 적는 게 너무 귀찮았습니다.
그래서 어떻게든 엑셀을 쓰지 말자라는 생각으로 삽질자동화를 열심히 진행했던 내용을 적어 보려고 합니다.
핵심 아이디어: OCR
앱에서 카드 사용내역 정보를 얻는 방법은 크게 2가지 정도가 생각이 났습니다.
첫 번째는 카드승인 시 오는 알림 등에서 패킷을 긁어 정보를 빼내는 건데... 그다지 자신이 없고 설사 가능하더라도 보안을 뚫는 느낌이라 바람직한 방법은 아니라고 생각했습니다. 그래서 다른 방법을 생각했고 그 방법은 바로 스크린샷을 찍어 OCR 인식으로 내역을 추출하는 것이었습니다.
문제는 오픈소스(무료) OCR 도구의 한글 인식률이 영 좋지 않다는 점이었습니다. 여러 시행착오를 거쳐 보았지만 번거롭기만 하고 결과도 그리 만족스럽지 않았습니다. 결국 생각나는 것은 네이버◦카카오 등 국내에서 제공하는 OCR인데, 유료라는 점이 역시 걸렸습니다.
그러던 중 CLOVA OCR 체험 페이지를 찾게 되었는데, 체험 명목으로 적은 양이지만 무료로 사진 몇 개를 업로드해 OCR 결과를 받을 수 있었습니다. 그래서 해당 페이지를 Selenium으로 조작해 OCR 인식 결과를 얻으면 되겠다는 생각을 했고, 실제로 만족스러운 결과를 얻을 수 있었습니다.
이전 방식: FastAPI
OCR 문제는 해결되었고, 이제 스크린샷을 처리할 방법만 생각하면 되었습니다.
스크린샷은 모바일에서 찍을 텐데, 처리를 위해 컴퓨터에 옮기는 것도 하나의 일이라고 생각했습니다.
그래서 가장 먼저 생 각난 것이 REST API였습니다.
바로 FastAPI로 파일을 받아서, OCR로 처리하고 자동으로 엑셀까지 작성해 다운로드할 수 있도록 작업했습니다. 작업에 시간이 걸리기 때문에, 백그라운드 작업으로 처리하도록 하였습니다. 실사용까지 성공은 했는데, 몇 가지 문제가 있었습니다.
- 사용량이 적었습니다. 이를 위해 VM을 올리는 것은 다소 낭비였습니다.
- Selenium은 브라우저를 돌려야 하기 때문에 무료 VM으로는 메모리 압박이 심했습니다.
- VM에서 백그라운드로 돌리다 보니 에러 로깅이 쉽지 않았습니다. 파일로 로그를 빼는 등 방법이 없는 것은 아니었지만 배보다 배꼽이 더 크기도 하고...
그러다가 기존에 VM을 띄워 놓았던 Oracle Cloud 계정이 개인적인 문제로 터지면서(...) 이 방법은 폐기하게 되었습니다.
현재 방식: Google Drive API
곰곰이 생각해 보니, 엑셀 파일은 어차피 메일로 보내야 하고 이래저래 개인 컴퓨터에서 코드를 돌려도 상관없겠다 싶었습니다. 그리고 모바일로 파일을 올리고 처리할 수 있는 다른 방법으로 클라우드 스토리지가 머리를 스쳐갔습니다. 가장 친숙한 Google Drive로 실행에 옮겨 보기로 했습니다.
그래서 다음과 같은 식으로 코드를 작성했습니다.
import os
import shutil
import config
from func.gdrive import gdrive_down, gdrive_up_excel
from func.img_process import crop_and_save
from func.ocr import make_excel_ocr
IMG_FOLDER = "download"
# 폴더 세팅
if os.path.exists(IMG_FOLDER):
shutil.rmtree(IMG_FOLDER)
os.makedirs(IMG_FOLDER, exist_ok=True)
# 파일 다운로드
gdrive_down(folderName=config.GDRIVE_FOLDER_NAME)
# 파일 전처리
for file in os.listdir(IMG_FOLDER):
crop_and_save(fileName=file, folder=IMG_FOLDER)
# 파일 CLOVA로 OCR 처리해서 엑셀 작성
fileName = make_excel_ocr(
folderName=IMG_FOLDER,
cardName=config.CARD_NAME,
name=config.NAME,
year=config.YEAR,
month=config.MONTH
)
# 엑셀 파일 업로드
gdrive_up_excel(fileName=fileName)
파일 전처리는 간단히 Pillow
패키지를 사용해 이미지를 자르는 과정이고, OCR을 통한 처리는 기존대로 Selenium을 활용했습니다.
Google Drive API를 사용하기 위해서는 초기 설정이 필요한데, 이 부분은 공식 문서에 잘 설명되어 있습니다. 오히려 이후에 Python 패키지를 사용하는 과정이 번거로웠습니다. 구글에서 제공하는 예제가 2% 부족하고, 과거 API 버전 기준의 정보도 다수 혼재해 있었기 때문입니다. 그래도 간단한 다운로드◦업로드만 구현하면 되었기 때문에 몇 가지 참고 자료를 찾아가며 진행했습니다.
핵심 로직은 변경이 없었기 때문에 추가적인 공수가 많이 들어가지 않았고, 현재 문제없이 사용 중입니다.
이 정도면 소기의 목적을 달성해서 만족스럽게 사용할 수 있을 것 같네요.