Python for real work

반복 업무를 줄이는
실전 파이썬 자동화

복사·붙여넣기, 엑셀 정리, 웹 데이터 수집, API 연동처럼 시간을 빼앗는 작업을 코드로 바꾸는 과정을 단계별로 설명합니다.

업무 자동화 시작하기

필요한 해결책부터 찾으세요

목적별 가이드에서 관련 코드와 오류 해결 방법을 빠르게 찾을 수 있습니다.

01

업무 자동화

반복 작업, 스케줄 실행, 파일 처리와 GUI 도구 제작을 다룹니다.

02

웹 스크래핑

Requests, BeautifulSoup, Selenium으로 공개 데이터를 수집합니다.

03

데이터 처리

CSV·엑셀·JSON을 정리하고 분석 가능한 형태로 바꿉니다.

04

API·운영

외부 서비스 연동, 인증, 오류 처리와 안정적인 실행을 설명합니다.

최근 실전 가이드

글

파이썬 urljoin 상대 링크 변환: 슬래시, 상위 경로, 쿼리를 구분하기

수집한 href는 기준 문서 URL과 urljoin으로 결합하되, 경로 앞뒤 슬래시와 결합 후 호스트를 별도로 확인하세요. 확인일: 2026-10-25. Python 3.14 표준 라이브러리 예제이며, Windows Python 3.14.4에서 합성 입력으로 실행하고 assert 검사를 통과했습니다. 문자열 더하기로 링크를 만들면 왜 틀리나요? HTML에서 찾은 href는 detail.html, ../summary.html, /download.csv처럼 서로 다른 기준을 가질 수 있습니다. 사이트 주소와 문자열로 붙이면 상위 경로나 쿼리 전용 링크를 잘못 해석할 수 있습니다. 이 글은 네트워크 수집 전에 링크를 계산하는 단계만 다루며 실제 사이트에 요청하지 않습니다. example.invalid와 other.invalid는 합성 주소입니다. 입력 기준 URL을 문서 주소로 고정합니다 기준은 https://example.invalid/reports/2026/index.html입니다. detail.html은 같은 디렉터리, ../summary.html은 한 단계 위, /download.csv는 사이트 루트에서 시작합니다. ?page=2는 현재 문서의 쿼리를 바꾸고 #table은 문서 내 위치를 붙입니다. 아래 사례별 예상 URL을 assert로 비교하므로 출력 문자열을 직접 대조할 수 있습니다. 직접 실행하는 예제 from urllib.parse import urljoin base = "https://example.invalid/reports/2026/index.html" cases = { "detail.html": "https://example.invalid/reports/2026/detail.html", "../summary.html": "https://example.invalid/reports/summary.html", "/download...

파이썬 SQLite 두 테이블 저장: 두 번째 INSERT 실패 시 함께 롤백하기

함께 성공해야 하는 INSERT를 같은 연결의 트랜잭션으로 묶고, 예외를 with 블록 밖에서 처리하세요. 확인일: 2026-10-25. Python 3.14 표준 라이브러리 예제이며, Windows Python 3.14.4에서 합성 입력으로 실행하고 assert 검사를 통과했습니다. 두 번의 저장이 하나의 작업이어야 하는 이유 자료 본문을 items에 넣고 처리 이력을 job_events에 따로 넣는 자동화를 생각해 보세요. 첫 저장 뒤 commit하고 이력 저장이 실패하면 본문만 남을 수 있습니다. 이 글은 중복 항목을 갱신하는 UPSERT가 아니라, 서로 연결된 두 저장의 성공·실패 경계를 맞추는 방법을 다룹니다. 예제는 메모리 DB와 가상 문서만 사용합니다. 예제의 입력과 실패 조건 items의 id와 job_events의 job_id는 각각 기본 키입니다. 첫 호출은 A01과 job-1을 저장합니다. 다음 호출은 새 문서 B02를 넣은 뒤 이미 있는 job-1을 또 저장해 두 번째 INSERT에서 IntegrityError가 나도록 구성했습니다. 예상 결과는 A01과 첫 이력만 남고 B02는 없는 것입니다. SQL 값은 문자열 보간 대신 자리표시자로 전달합니다. 직접 실행하는 예제 import sqlite3 def save_item(conn, item_id, name, job_id): with conn: conn.execute("INSERT INTO items VALUES (?, ?)", (item_id, name)) conn.execute("INSERT INTO job_events VALUES (?, ?)", (job_id, item_id)) conn = sqlite3.connect(":memory:", autocommit=False) try: conn.execute("CREATE TABLE items (id TEXT PRIMARY KEY, ...

파이썬 JSON 설정 읽기: 중복 키와 NaN을 조용히 허용하지 않는 방법

JSON 설정의 중복 키는 object_pairs_hook으로, NaN·Infinity는 parse_constant로 거부하고 자료형 검증은 별도로 수행하세요. 확인일: 2026-10-24. Python 3.14 표준 라이브러리 예제입니다. Windows Python 3.14.4에서 합성 입력으로 로컬 실행과 assert 검사를 통과했습니다. 문법이 맞는데 설정값이 달라지는 이유는 무엇인가요? 같은 JSON 객체에 retry가 두 번 있으면 Python의 기본 디코더는 마지막 값을 남길 수 있습니다. 작성자가 의도하지 않은 값으로 설정이 바뀌어도 파싱 자체는 성공합니다. 이 글은 이미 읽은 사전에서 누락 키를 찾는 문제가 아니라, 사전으로 만들기 전에 중복 이름을 발견하는 문제를 다룹니다. 두 가지 훅은 각각 무엇을 검사하나요? object_pairs_hook은 각 JSON 객체의 이름·값 쌍 목록을 받아 객체로 바꿉니다. unique_object에서 이미 본 이름이 나오면 고정 메시지의 ValueError를 냅니다. 중첩 객체에도 적용됩니다. parse_constant는 NaN, Infinity, -Infinity 같은 비표준 숫자 표기를 만났을 때 거부하도록 설정합니다. 따옴표로 감싼 "NaN"은 평범한 문자열이므로 이 예제에서는 허용합니다. 합성 입력으로 정상과 오류를 나눕니다 아래 read_config는 최상위 값이 객체인지도 확인합니다. 정상 설정과 중첩 true 값을 읽은 뒤, 같은 객체의 중복 이름·중첩 중복·비표준 숫자 상수·최상위 배열·마지막 쉼표를 검사합니다. 일반 문법 오류의 JSONDecodeError도 ValueError의 하위 클래스라 같은 테스트에서 잡힙니다. 실제 회사 설정이나 외부 API는 읽지 않습니다. import json def unique_object(pairs): result = {} for key, value in pairs: if key in result: ...

파이썬 argparse 입력 검증: 필수 옵션, 허용 값, 처리 건수 제한하기

자동화 실행 인자는 argparse에서 필수 여부·허용 값·범위를 검사하고, 실제 반영은 별도 명시 옵션으로 분리하세요. 확인일: 2026-10-24. Python 3.14 표준 라이브러리 예제입니다. Windows Python 3.14.4에서 합성 입력으로 로컬 실행과 assert 검사를 통과했습니다. 왜 실행 인자를 먼저 검사해야 하나요? 스케줄러에서 같은 프로그램을 반복 실행할 때 옵션을 빠뜨리거나 대상을 오타로 입력하면, 잘못된 자료를 처리할 수 있습니다. 이 예제는 데이터 조회나 변경보다 앞에 두는 명령줄 입력 검증 계층입니다. source는 sales 또는 support, limit는 1~1000 정수로 제한합니다. 이 숫자는 서비스 한도가 아니라 합성 예제의 입력 계약입니다. 기본 동작을 어떻게 정하나요? --source는 반드시 입력해야 하고 --limit를 생략하면 100입니다. --apply는 존재할 때만 True가 되는 플래그로 기본 False입니다. allow_abbrev=False로 --sou 같은 긴 옵션의 축약을 허용하지 않습니다. 옵션을 정확히 적도록 하는 선택이며 모든 CLI의 보편적인 필수 설정은 아닙니다. 최소 예제와 실패 조건 아래 코드는 인자 분석기와 자체 테스트입니다. 실제 파일이나 API를 처리하는 함수는 없습니다. 따라서 --apply를 넣어도 이 코드 자체가 운영 자료를 변경하지 않습니다. 실제 프로그램에는 분석 결과를 확인한 뒤 미리보기와 반영 함수를 분기하는 호출부를 별도로 작성해야 합니다. import argparse from contextlib import redirect_stderr from io import StringIO def bounded_limit(text): try: value = int(text) except ValueError: raise argparse.ArgumentTypeError("정수가 필요합니다") from None ...

파이썬 실행 로그에 비밀값을 넣지 않기: 허용 필드형 JSON 이벤트 만들기

원본 응답을 로거에 넘기지 말고, 허용한 작업명·실행 ID·상태·처리 건수만 검증해 기록하세요. 적용 환경: Python 3.14 표준 라이브러리. 2026-10-23 확인. Windows Python 3.14.4에서 아래 합성 예제를 임시 작업 폴더로 실행해 assert와 예상 예외 검사를 통과했습니다. 실제 회사 파일·API·GUI는 실행하지 않았습니다. 문자열에서 비밀값을 지우기 전에 입력을 줄이세요 자동화 결과를 확인하려고 headers, 요청 URL, 응답 본문이나 설정 사전 전체를 출력하면 토큰·개인정보가 함께 기록될 수 있습니다. 이 글은 모든 패턴을 마스킹하는 필터 대신 기록할 데이터 자체를 적게 만드는 예제입니다. 원본 응답 객체를 함수가 받지 않게 하고, 결과 요약 이벤트만 새로 구성합니다. 이것만으로 프로그램의 모든 로그 경로가 안전해지는 것은 아닙니다. 허용 이벤트의 계약을 정의합니다 가상 작업명은 inventory_sync 또는 daily_report, 상태는 completed 또는 failed 중 하나입니다. processed는 bool이 아닌 0~1000000 정수이며, run_id는 영문 소문자·숫자·하이픈으로 된 1~40자 문자열입니다. 이 범위는 예제에서 정한 계약입니다. 정규식이 문자열의 비밀 여부를 판단하지는 못하므로 실행 ID에는 이메일·토큰을 재사용하지 말고 별도로 생성한 비민감 식별자를 넣어야 합니다. 직접 실행하는 최소 예제 import io import json import logging import re def make_event(*, job, run_id, status, processed): if job not in {"inventory_sync", "daily_report"}: raise ValueError("허용되지 않은 작업") if not isinstance(run_id, str) or re.fullmatch(r"...

파이썬 CSV 두 파일 비교: ID 기준으로 추가, 삭제, 수정 행 구분하기

고유 ID로 각 CSV를 색인하고, ID 집합의 차이와 공통 ID의 비교 필드를 나눠 검사하세요. 적용 환경: Python 3.14 표준 라이브러리. 2026-10-23 확인. Windows Python 3.14.4에서 아래 합성 예제를 임시 작업 폴더로 실행해 assert와 예상 예외 검사를 통과했습니다. 실제 회사 파일·API·GUI는 실행하지 않았습니다. 파일 전체 비교와 업무 항목 비교는 다릅니다 매일 내려받는 자산 목록의 줄 순서만 바뀌었을 때, 파일 해시나 줄 단위 차이는 달라질 수 있습니다. 그러나 같은 자산의 소유 부서와 상태가 같다면 업무 변경은 아닐 수 있습니다. 이 글에서는 파일의 바이트 일치가 아니라 고유 자산 ID를 기준으로 의미 있는 필드가 변했는지 비교합니다. 원본 목록에 없는 ID가 보인다는 사실과 실제 자산을 폐기해야 한다는 판단도 분리합니다. 비교할 필드와 키 규칙을 먼저 고정합니다 합성 CSV의 헤더는 asset_id,owner_team,state이며 순서까지 고정합니다. asset_id는 문자열이라 001의 앞자리 0을 보존합니다. owner_team과 state 두 값의 튜플이 같으면 변경 없음입니다. ID 앞뒤 공백과 중복 ID, 빈 값·누락 열·추가 열은 실패시키며, 부서나 상태의 공백을 임의로 정제하지 않습니다. 시간 같은 변동 필드가 추가되면 비교 대상에 넣을지 먼저 결정하세요. 직접 실행하는 최소 예제 import csv from io import StringIO FIELDS = ["asset_id", "owner_team", "state"] def load_snapshot(text): reader = csv.DictReader(StringIO(text, newline=""), strict=True) if reader.fieldnames != FIELDS: raise ValueError("헤더 불일치...

파이썬 최신 보고서 파일 선택: 수정 시간 대신 파일명 날짜와 중복 검사

파일명에서 업무 날짜를 검증해 기준일 이하의 최신 날짜를 찾고, 같은 날짜 후보가 여러 개면 자동 선택을 중단하세요. 적용 환경: Python 3.14 표준 라이브러리. 2026-10-22 확인. Windows Python 3.14.4에서 아래 예제를 임시 작업 폴더에서 실행하고 assert 및 예상 예외 검사를 통과했습니다. 실제 회사 자료·외부 서비스는 사용하지 않았습니다. 업무 날짜와 파일 수정 시간은 다릅니다 수정 시간은 파일 시스템 메타데이터이고 보고서가 집계한 날짜 자체가 아닙니다. 오래된 보고서를 다시 저장하거나 전송 도구가 시간을 바꾸면 수정 시간 순서와 업무 날짜 순서가 달라질 수 있습니다. 복사 도구가 시간을 보존하는 경우도 있으므로 복사하면 항상 수정 시간이 바뀐다고 가정하지 마세요. 파일명 날짜를 신뢰하려면 생성 측과 명명 규칙을 먼저 합의해야 합니다. 선택할 이름 규칙과 기준일을 명시합니다 예제는 폴더 바로 아래의 report_YYYY-MM-DD.csv 또는 report_YYYY-MM-DD_rev2.csv 같은 이름만 후보로 받습니다. rev 뒤에는 1 이상의 정수를 허용합니다. 확장자는 소문자 .csv로 고정하고 임시 파일·다른 접두사·하위 폴더는 처리하지 않습니다. 기준일은 date(2026, 10, 22)로 주입해 테스트가 실행 날짜에 따라 달라지지 않게 했습니다. 직접 실행하는 최소 예제 from pathlib import Path from datetime import date from tempfile import TemporaryDirectory import os import re NAME = re.compile(r"report_([0-9]{4}-[0-9]{2}-[0-9]{2})(?:_rev[1-9][0-9]*)?\.csv") def select_report(folder, as_of): candidates = [] for path in Path(folder).iterdir(): ...