반응형
웹 개발, 크롤링, 내부 API 연동까지… 파이썬에서 HTTP를 다룬다면 가장 먼저 떠오르는 라이브러리가 바로 requests
입니다. “인간을 위한(human-friendly)” API를 표방할 만큼 문법이 직관적이고 실무 채택률도 매우 높죠. 이 글에서는 requests
의 핵심 사용법을 정리하고, HTTPX, urllib3, aiohttp, urllib.request(표준 라이브러리) 와 비교해 언제 무엇을 선택할지 명확하게 안내합니다. 각 라이브러리별 장단점, 코드 예제, 베스트 프랙티스까지 한 번에 정리해 드려요.
1) 왜 requests
인가?
- 가독성/간결성 최고:
requests.get(url)
만으로도 충분히 읽기 쉽고 직관적 - 세션/쿠키 관리:
Session()
으로 커넥션 재사용, 쿠키 자동 유지 - 폼/JSON/파일 업로드가 쉬움
- 광범위한 문서/예시/질문답변: 문제 생겨도 검색이 잘 됨
import requests
# GET + 쿼리스트링
r = requests.get("https://api.example.com/search", params={"q": "python"})
r.raise_for_status()
data = r.json()
# POST JSON
r = requests.post("https://api.example.com/login", json={"id": "kim", "pw": "1234"})
token = r.json()["token"]
# 세션 재사용(쿠키/커넥션)
with requests.Session() as s:
s.headers.update({"Authorization": f"Bearer {token}"})
r1 = s.get("https://api.example.com/me")
r2 = s.post("https://api.example.com/upload", files={"file": open("a.png", "rb")})
2) 비교 대상 한눈에 보기
라이브러리 | 동기/비동기 | 강점 | 약점 | 추천 상황 |
---|---|---|---|---|
requests | 동기 | 쉬운 문법, 에코시스템 풍부, 학습 곡선 낮음 | 비동기 부재, HTTP/2 한계 | 빠르게 안정적인 동기 코드 필요 시 |
HTTPX | 동기 + 비동기 | requests 와 유사 API, async 지원, HTTP/2 |
자료가 상대적으로 적음 | 비동기/HTTP/2 필요할 때 |
urllib3 | 동기 | 저수준 제어, 리트라이, 커넥션 풀 | 코드 장황 | 고급 커스텀 제어 필요 시 |
aiohttp | 비동기 | 고성능 동시성, 스트리밍, 웹소켓 | async/await 학습 필요 | 대량 동시 요청/웹소켓 |
urllib.request | 동기 | 표준 라이브러리 | 사용성 낮음 | 패키지 설치 제한 환경 |
3) 실전 예제 모음
3-1. requests
기본/중급
import requests
try:
r = requests.get("https://example.com/api", timeout=(3.05, 10))
r.raise_for_status()
except requests.Timeout:
print("타임아웃!")
except requests.HTTPError as e:
print("HTTP 에러:", e.response.status_code)
import requests
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
s = requests.Session()
retry = Retry(total=5, backoff_factor=0.5, status_forcelist=[429, 500, 502, 503, 504])
s.mount("https://", HTTPAdapter(max_retries=retry))
r = s.get("https://api.example.com/stable-endpoint", timeout=10)
# 대용량 다운로드
with requests.get("https://example.com/big.zip", stream=True) as r:
with open("big.zip", "wb") as out:
for chunk in r.iter_content(chunk_size=1024*64):
out.write(chunk)
3-2. HTTPX 동기/비동기
import httpx
with httpx.Client(http2=True) as client:
r = client.get("https://www.example.com")
print(r.text[:200])
import asyncio, httpx
async def fetch(client, url):
r = await client.get(url)
return r.text[:80]
async def main():
urls = [f"https://httpbin.org/delay/1?i={i}" for i in range(10)]
async with httpx.AsyncClient(http2=True) as client:
results = await asyncio.gather(*(fetch(client, u) for u in urls))
print(results)
asyncio.run(main())
3-3. aiohttp (비동기 + 웹소켓)
import asyncio, aiohttp
async def fetch(session, url):
async with session.get(url) as r:
return await r.text()
async def main():
urls = [f"https://httpbin.org/delay/1?i={i}" for i in range(20)]
async with aiohttp.ClientSession() as session:
results = await asyncio.gather(*(fetch(session, u) for u in urls))
print(len(results))
asyncio.run(main())
3-4. urllib3
import urllib3, json
http = urllib3.PoolManager()
r = http.request("GET", "https://httpbin.org/json")
data = json.loads(r.data.decode())
print(data["slideshow"]["title"])
3-5. urllib.request
from urllib.request import Request, urlopen
import json
req = Request("https://httpbin.org/get", headers={"User-Agent": "Stdlib"})
with urlopen(req) as resp:
body = resp.read().decode()
print(json.loads(body))
4) 베스트 프랙티스
- 항상 타임아웃 지정
- 리트라이 + 백오프 전략
- 세션/커넥션 재사용
- 스트리밍 다운로드
- 지표/로깅
- 헤더/캐시 제어
- SSL/프록시 정책 명확화
- 비동기 필요성 판단
- HTTP/2 고려
- 우아한 종료
5) 선택 가이드
- 내부 API/크롤링 → requests
- 향후 비동기 확장 → HTTPX
- 고급 커스텀 제어 → urllib3
- 대규모 동시성/웹소켓 → aiohttp
- 패키지 설치 제한 → urllib.request
6) 마무리
빠르고 안전한 동기 HTTP 호출이 목적이라면 requests가 기본값입니다. 성능/동시성/HTTP/2/웹소켓이 핵심이라면 HTTPX 또는 aiohttp를 고려하세요. 장기적으로는 타임아웃/리트라이 표준화, 로깅/메트릭을 팀 규약으로 묶어두면 운영 품질이 크게 올라갑니다.
반응형
'DEVEL > PYTHON' 카테고리의 다른 글
Python - 맥OS에서 파이썬 설치 및 개발하기 (0) | 2025.09.02 |
---|---|
Python Playwright를 이용한 스크래핑 (4) | 2024.08.31 |
PYTHON 두장의 이미지 합성하기 (0) | 2024.04.09 |
PYTHON ChatGPT API 예제 (0) | 2023.07.25 |
PYTHON 내 주소에 이더리움 거래 조회 (0) | 2023.07.18 |