중복 파일 삭제 스크립트를 돌렸다가 식은땀 흘린 날

이미지
중복 파일 삭제 스크립트를 돌렸다가 식은땀 흘린 날 이 블로그의 중복 파일 자동 삭제 편 과 파일명 일괄 변경 편 을 보면 공통적으로 "DRY_RUN"이라는 안전장치가 들어 있습니다. 실제 삭제나 변경 전에 미리보기부터 하도록 만든 이 습관은, 사실 처음부터 있던 게 아니라 한 번의 아찔한 경험 뒤에 생긴 것입니다. 당시 상황은 이랬습니다. 다운로드 폴더가 오래 방치되어 있어 용량을 확인해보니 중복 파일이 상당히 많았고, "파일 해시값을 비교해서 중복이면 자동으로 지우는" 스크립트를 처음 짜서 바로 실행했습니다. 사건 발생 — 실행 버튼을 누른 직후 처음 짠 코드는 대략 이런 형태였습니다. import hashlib from pathlib import Path from collections import defaultdict folder = Path(r"C:\Users\내이름\Downloads") hash_map = defaultdict(list) def get_hash(filepath): h = hashlib.md5() with open(filepath, "rb") as f: h.update(f.read()) return h.hexdigest() for file in folder.rglob("*"): if file.is_file(): hash_map[get_hash(file)].append(file) # 중복이면 첫 번째만 남기고 나머지 삭제 for files in hash_map.values(): if len(files) > 1: for f in files[1:]: f.unlink() # ← 바로 삭제 실행 print(f"삭제: {f.name}") 실행하자마자 터미널에 "삭제: ......

pypdf vs PyMuPDF vs reportlab, PDF 처리 뭐가 다를까? 파이썬 비교분석

이미지
pypdf vs PyMuPDF vs reportlab, PDF 처리 뭐가 다를까? 파이썬 비교분석 이 블로그의 PDF 관련 글들을 보면 라이브러리가 조금씩 다릅니다. PDF 자동 병합 편 과 PDF 텍스트 추출 편 은 pypdf , PDF 자동 압축 편 은 PyMuPDF(fitz) , PDF 도장 삽입 편 은 pypdf 와 reportlab 을 함께 사용했습니다. 왜 매번 다른 도구를 썼는지, 이번 글에서 세 라이브러리의 역할을 명확히 정리해보겠습니다. 세 라이브러리, 한 줄 요약 pypdf → 기존 PDF를 "자르고 합치고 읽는" 라이브러리. 가볍고 빠름. PyMuPDF → PDF 내부(이미지, 텍스트, 구조)까지 깊이 파고드는 라이브러리. 강력하지만 무거움. reportlab → PDF를 "처음부터 새로 그리는" 라이브러리. 편집이 아닌 생성 전용. 셋 다 "PDF를 다룬다"는 공통점이 있지만, pypdf는 편집, PyMuPDF는 분석·변환, reportlab은 생성 이라는 서로 다른 용도로 설계되었습니다. 같은 작업을 각각 어떻게 처리하는지 비교해보면 이 차이가 명확해집니다. 비교 1 — 여러 PDF를 하나로 합치기 pypdf (가장 간단하고 빠름) from pypdf import PdfWriter writer = PdfWriter() for pdf in ["file1.pdf", "file2.pdf", "file3.pdf"]: writer.append(pdf) writer.write("합본.pdf") # 3줄로 끝남. 페이지 순서만 그대로 이어 붙이는 작업이라 매우 가벼움 PyMuPDF (가능은 하지만 더 무거움) import fitz merged = fitz.open() for path in ["file1.pdf", "file2.pdf...

엑셀 일정표를 구글 캘린더에 자동 등록하기! 파이썬 캘린더 자동화

이미지
엑셀 일정표를 구글 캘린더에 자동 등록하기! 파이썬 캘린더 자동화 (완성 코드 공개) "거래처와 잡힌 미팅 10건을 엑셀로 정리했는데 캘린더에는 또 하나씩 입력해야 한다", "프로젝트 마감일 목록을 팀원 전체 캘린더에 동시에 등록해야 한다", "정기 점검 일정을 매달 캘린더에 반복 입력하는 게 번거롭다"… 이 블로그의 구글 스프레드시트 자동화 편 에서 소개한 것과 같은 방식의 구글 API 인증을 활용하면, 엑셀에 정리된 일정 목록을 구글 캘린더에 자동으로 등록할 수 있습니다. 참석자 초대, 알림 시간 설정까지 코드 한 번 실행으로 처리됩니다. 1단계: 구글 캘린더 API 설정 (최초 1회만) 구글 스프레드시트 연동 편과 마찬가지로 구글 클라우드에서 API를 활성화해야 합니다. 이미 이전 게시글에서 서비스 계정을 만들어보셨다면 아래 3~4번만 추가하면 됩니다. Google Cloud Console (console.cloud.google.com)에서 프로젝트를 선택하거나 새로 만듭니다. "API 및 서비스" → "라이브러리" 에서 "Google Calendar API" 를 검색해 "사용 설정" 합니다. 기존에 만들어둔 서비스 계정이 있다면 그대로 사용하고, 없다면 "사용자 인증 정보" 에서 서비스 계정을 새로 만들고 JSON 키를 발급받습니다. 구글 캘린더(calendar.google.com)를 열고 등록하려는 캘린더의 "설정 및 공유" 에서 서비스 계정 이메일(JSON 파일의 client_email 값)을 "일정 변경 권한" 으로 공유합니다. ⚠️ 마지막 설정이 가장 중요합니다: 캘린더 공유 설정을 빠뜨리면 API는 정상 작동하지만 "권한 없음" 오류가 발생합니다. 반드시 캘린더 설정에서 서비스 계정 이메일을 추가하...

매일 아침 자동 알림 만들려다 겪은 3번의 삽질

이미지
매일 아침 자동 알림 만들려다 겪은 3번의 삽질 이 블로그의 스케줄러 편 과 텔레그램 자동 발송 편 을 각각 소개했었는데, 사실 이 둘을 실제로 연결해서 "매일 아침 9시에 날씨와 환율을 텔레그램으로 받는" 시스템을 만들 때는 생각보다 여러 번 헛발질을 했습니다. 이번 글에서는 그 과정을 그대로 공유합니다. 목표는 단순했습니다. 매일 아침 출근 전에 오늘 날씨와 환율을 텔레그램으로 자동으로 받는 것. 코드 자체는 기존에 소개한 두 게시글을 합치기만 하면 될 것 같았는데, 실제로는 세 번의 실패를 거쳤습니다. 시도 1 — 노트북을 덮으면 알림이 안 옴 처음에는 schedule 라이브러리로 단순하게 만들었습니다. import schedule import time def send_morning_briefing(): # 날씨 API 호출 + 텔레그램 발송 코드 pass schedule.every().day.at("09:00").do(send_morning_briefing) while True: schedule.run_pending() time.sleep(30) 터미널을 켜둔 채로 테스트했을 때는 정확히 9시에 알림이 왔습니다. 그런데 다음 날 아침, 알림이 오지 않았습니다. 무엇이 잘못됐나: 전날 밤에 노트북 뚜껑을 덮고 퇴근했는데, 절전 모드로 들어가면서 파이썬 스크립트도 함께 멈췄던 것입니다. schedule 라이브러리는 PC가 켜져서 스크립트가 실제로 돌아가고 있는 동안에만 동작한다는 당연한 사실을, 실제로 겪고 나서야 체감했습니다. ❌ 실패 원인: "코드가 정확하면 당연히 실행되겠지"라고 생각했지, "실행 환경(PC 전원 상태)까지 자동화의 일부"라는 것을 고려하지 않았습니다. 시도 2 — 윈도우 작업 스케줄러로 옮겼더니, 이번엔 알림이 5번씩 옴 PC가 꺼져 있어도 동작하도록 윈도우 작업 스케줄러에 등...

requests+BeautifulSoup vs Selenium, 웹 크롤링 뭐가 다를까? 파이썬 비교분석

이미지
requests+BeautifulSoup vs Selenium, 웹 크롤링 뭐가 다를까? 파이썬 비교분석 이 블로그의 웹 데이터 자동 수집 편 에서는 requests 와 BeautifulSoup 을 사용했고, 웹사이트 자동 로그인 편 에서는 Selenium 을 사용했습니다. "둘 다 웹에서 데이터를 가져오는데 왜 다른 도구를 썼을까" 궁금하셨던 분들을 위해, 이번엔 같은 작업을 두 가지 방식으로 각각 구현해보면서 차이를 직접 비교해보겠습니다. 근본적인 차이 — 무엇을 읽어오는가 requests+BeautifulSoup → 서버가 처음 보내주는 "날것의 HTML"만 읽음 Selenium → 실제 브라우저를 띄워서 자바스크립트가 실행된 "최종 화면"을 읽음 이 한 줄이 모든 차이의 근원입니다. 요즘 많은 웹사이트는 페이지가 처음 열릴 때는 빈 뼈대만 오고, 자바스크립트가 실행되면서 실제 내용(상품 목록, 가격 등)이 채워지는 방식으로 만들어집니다. requests 는 이 자바스크립트를 실행하지 못하기 때문에, 이런 사이트에서는 빈 껍데기만 가져오게 됩니다. 비교 1 — 같은 뉴스 목록 페이지 크롤링하기 정적인 뉴스 목록 페이지(자바스크립트 없이 서버가 완성된 HTML을 바로 보내주는 경우)를 크롤링하는 상황을 가정합니다. requests + BeautifulSoup import requests from bs4 import BeautifulSoup import time start = time.time() res = requests.get("https://example-news.com/list") soup = BeautifulSoup(res.text, "html.parser") titles = [t.get_text(strip=True) for t in soup.select(".news-title")...

사진 여러 장을 PDF 한 장으로! 파이썬으로 이미지 자동 합치기

이미지
사진 여러 장을 PDF 한 장으로! 파이썬으로 이미지 자동 합치기 (완성 코드 공개) "영수증 10장을 스마트폰으로 찍었는데 회계팀에는 PDF 한 개로 보내야 한다", "계약서를 스캔 앱으로 여러 장 찍었는데 순서대로 하나의 문서로 만들어야 한다", "제품 사진 여러 장을 카탈로그처럼 PDF 한 권으로 정리하고 싶다"… 사진 여러 장을 PDF 하나로 합치는 작업은 온라인 변환 사이트를 이용할 수도 있지만, 파일을 업로드하고 순서를 맞추고 다운로드하는 과정이 매번 번거롭고 민감한 문서라면 외부 사이트 업로드가 꺼려질 수 있습니다. 파이썬을 한 번만 세팅해두면 폴더 안의 이미지를 파일명 순서대로 자동 정렬해 PDF로 합치고, 페이지 크기도 자동으로 맞춰줍니다. 1단계: 준비물 설치 파이썬이 설치되어 있어야 합니다. 없다면 python.org 에서 최신 버전을 받아 설치하세요. 설치 시 반드시 "Add Python to PATH" 에 체크해야 합니다. 이미지-PDF 변환에 필요한 라이브러리를 설치합니다. 터미널(윈도우: CMD 또는 파워셸)을 열고 아래 명령어를 실행하세요: pip install pillow pillow 는 이미지를 읽고 처리하는 라이브러리인 동시에, 여러 이미지를 하나의 PDF로 저장하는 기능도 기본으로 지원합니다. 별도의 PDF 전용 라이브러리 없이 이 하나로 충분합니다. 💡 이 코드로 할 수 있는 것: 폴더 안의 jpg, png 이미지를 파일명 순서대로 자동 정렬해 하나의 PDF로 합칩니다. 이미지 크기가 제각각이어도 페이지 크기를 자동으로 맞춰주고, PNG의 투명 배경도 흰 배경으로 자동 변환해 PDF 저장 오류를 방지합니다. 2단계: 완성 코드 아래 코드를 그대로 복사해서 메모장에 붙여넣고, images_to_pdf.py 로 저장하세요. 저장 시 파일 형식은 "모든 파일" , 인코딩은 UTF-8 로 설정합...

처음 시도한 업무 자동화, 3번 실패하고서야 깨달은 것들

이미지
처음 시도한 업무 자동화, 3번 실패하고서야 깨달은 것들 이 블로그에는 "완성 코드"만 올라오지만, 사실 모든 자동화가 처음부터 깔끔하게 완성되지는 않습니다. 이번 글에서는 실제로 겪었던 시행착오 하나를 그대로 풀어보려 합니다. 지금까지 소개한 완성 코드들이 왜 지금의 형태가 되었는지, 그 뒤에 있는 실패 과정을 공유하면 자동화를 처음 시도하는 분들께 더 도움이 될 것 같았습니다. 상황은 이랬습니다. 거래처별로 흩어진 엑셀 파일 수십 개를 매달 하나로 합쳐서 정리하는 작업을, 파이썬으로 자동화하기로 마음먹었습니다. 시도 1 — "일단 되겠지" 하고 짠 코드, 반나절 만에 무너짐 처음에는 이렇게 단순하게 접근했습니다. import pandas as pd from pathlib import Path all_data = [] for file in Path("거래처파일").glob("*.xlsx"): df = pd.read_excel(file) all_data.append(df) result = pd.concat(all_data) result.to_excel("합친결과.xlsx") 파일 5개로 테스트했을 때는 잘 됐습니다. 문제는 실제 폴더에 파일 40개를 넣고 돌렸을 때 터졌습니다. 무엇이 잘못됐나: 거래처마다 엑셀 헤더 이름이 조금씩 달랐습니다. 어떤 파일은 "거래처명", 어떤 파일은 "업체명"이었고, 어떤 파일은 1행이 아니라 2행부터 데이터가 시작했습니다. pd.concat() 은 이걸 그대로 합쳐버려서 결과 파일이 열 수십 개가 뒤죽박죽 섞인 형태로 나왔습니다. "일단 합치고 보자"는 접근이 실무 데이터의 비일관성 앞에서 완전히 무너진 순간이었습니다. ❌ 실패 원인: 테스트를 5개짜리 "깨끗한" 샘플로만 하고, 실제 40개 파일의 다양성을 확인하...