requests 라이브러리를 활용한 웹 요청 기본
Python에서 웹 서버와 통신할 때 requests 모듈은 가장 널리 사용되는 도구 중 하나다. 이 라이브러리는 HTTP GET 및 POST 요청을 간편하게 보내고 응답을 처리할 수 있도록 설계되어 있으며, 웹 스크래핑이나 API 연동 작업에 매우 유용하다.
GET 요청의 두 가지 방식
GET 요청은 주로 서버로부터 데이터를 조회할 때 사용되며, 파라미터 전달 방법에 따라 두 가지 접근법이 있다.
1. URL 직접 구성 방식
쿼리 문자열을 포함한 전체 URL을 직접 작성하여 요청을 보낸다. 이 방식은 간단하지만 가독성과 유지보수 측면에서 불리할 수 있다.
import requests
url = "https://www.baidu.com/s?wd=물류경제동향&sa=fyb_hp_news_31065"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
response = requests.get(url, headers=headers)
print("최종 요청 URL:", response.url)
print("서버 인코딩:", response.encoding)
# 응답 인코딩 설정 후 텍스트 출력
response.encoding = 'utf-8'
print(response.text)
2. params 인자 활용 방식
파라미터를 딕셔너리 형태로 분리하여 params 인자로 전달하면, requests가 자동으로 URL 인코딩을 수행하고 쿼리 스트링을 조합한다. 코드의 명확성과 확장성이 뛰어나다.
url = "https://www.baidu.com/s"
query_params = {
'wd': '물류경제동향',
'sa': 'fyb_hp_news_31065',
'from': '31065'
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
res = requests.get(url, headers=headers, params=query_params)
print("생성된 URL:", res.url)
URL 인코딩과 디코딩
특수 문자는 HTTP 요청 시 URL 안전 형식으로 인코딩되어야 한다. requests는 이를 위한 유틸리티 함수를 제공한다.
# URL 인코딩 예시
encoded = requests.utils.quote("물류경제동향")
print("인코딩 결과:", encoded) # %EB%AC%BC%EB%A5%98%EA%B2%BD%EC%A0%9C%EB%8F%99%ED%96%A5
# 디코딩 예시
decoded = requests.utils.unquote(encoded)
print("디코딩 결과:", decoded) # 물류경제동향
# 전체 URL 디코딩
print("원본 URL:", res.url)
print("디코딩된 URL:", requests.utils.unquote(res.url))
응답 데이터 처리 전략
서버 응답을 올바르게 해석하기 위해선 인코딩 방식을 정확히 설정해야 한다. 대표적으로 두 가지 방법이 있다.
방법 1: content + decode()
바이너리 데이터를 수동으로 지정된 인코딩으로 디코딩한다. 특히 인코딩이 혼란스러운 경우 유연하게 대응 가능하다.
raw_data = response.content
text_data = raw_data.decode('utf-8')
방법 2: text 속성 사용
requests가 자동으로 Content-Type 헤더를 기반으로 인코딩을 추론하므로, 대부분의 경우 편리하다. 필요 시 수동으로 인코딩을 지정할 수 있다.
response.encoding = 'utf-8'
content = response.text
JSON 응답 처리
API 응답 등 JSON 형식의 데이터는 .json() 메서드로 쉽게 파싱할 수 있다.
# JSON 응답 자동 파싱
try:
json_data = response.json()
print(json_data)
except ValueError:
print("응답이 유효한 JSON 형식이 아님")
POST 요청 사용 사례
로그인, 폼 제출, 대용량 데이터 전송 등에는 POST 메서드가 적합하다. 민감 정보 전송 시 GET보다 보안상 유리하다.
post_headers = {
"User-Agent": "Mozilla/5.0",
"Content-Type": "application/x-www-form-urlencoded"
}
payload = {
'username': 'user123',
'password': 'pass456',
'action': 'login'
}
login_url = 'https://example.com/login'
result = requests.post(login_url, data=payload, headers=post_headers)
if result.status_code == 200:
print("로그인 성공")
else:
print("실패:", result.status_code)
SSL 인증서 오류 처리
테스트 환경이나 자체 서명된 인증서를 사용하는 사이트에서는 SSL 검증 오류가 발생할 수 있다. 이를 우회하는 방법은 다음과 같다.
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
# SSL 경고 비활성화
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# verify=False로 요청
secure_response = requests.get(
'https://self-signed.badssl.com/',
verify=False,
headers={'User-Agent': 'Custom'}
)
주의: 프로덕션 환경에서는 verify=False 사용을 피하고, 신뢰할 수 있는 CA 인증서를 사용해야 한다.
응답 정보 확인
디버깅 또는 로깅 목적으로 다음 속성들을 활용할 수 있다.
print("응답 헤더:", response.headers)
print("쿠키:", response.cookies)
print("요청 헤더:", response.request.headers)
print("최종 URL:", response.url)