requests는 파이썬으로 HTTP 통신이 필요한 프로그램을 작성할 때 가장 많이 사용되는 라이브러리입니다. 특히 원격에 있는 API를 호출할 때 유용하게 사용할 수 있는데요. 이번 포스팅에서는 requests 라이브러리를 사용하는 방법에 대해서 알아보겠습니다. 파이썬의 패키지 매니저인 pip를 이용해서 requests 패키지을 설치합니다. $ pip install requests
Collecting requests
Downloading requests-2.25.0-py2.py3-none-any.whl (61 kB)
|████████████████████████████████| 61 kB 3.1 MB/s
Collecting urllib3<1.27,>=1.21.1
Downloading urllib3-1.26.2-py2.py3-none-any.whl (136 kB)
|████████████████████████████████| 136 kB 6.1 MB/s
Collecting certifi>=2017.4.17
Downloading certifi-2020.12.5-py2.py3-none-any.whl (147 kB)
|████████████████████████████████| 147 kB 4.9 MB/s
Collecting idna<3,>=2.5
Downloading idna-2.10-py2.py3-none-any.whl (58 kB)
|████████████████████████████████| 58 kB 8.6 MB/s
Collecting chardet<4,>=3.0.2
Downloading chardet-3.0.4-py2.py3-none-any.whl (133 kB)
|████████████████████████████████| 133 kB 6.7 MB/s
Installing collected packages: urllib3, certifi, idna, chardet, requests
Successfully installed certifi-2020.12.5 chardet-3.0.4 idna-2.10 requests-2.25.0 urllib3-1.26.2 설치가 잘 되었는지 파이썬 인터프리터를 실행하여 확인해봅니다. $ python
Python 3.9.0 (default, Oct 17 2020, 15:32:58)
[Clang 11.0.3 (clang-1103.0.32.62)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.get("//google.com")
<Response [200]> requests 라이브러리로 구글에 접속을 해보니 상태 코드 200이 응답이 되는 것을 볼 수 있습니다. 🎉 requests 라이브러리는 매우 직관적인 API를 제공하는데요. 어떤 방식(method)의 HTTP 요청을 하느냐에 따라서 해당하는 이름의 함수를 사용하면 됩니다. 온라인 서비스를 HTTP로 호출하면 상태 코드를 응답받게 됩니다. 일반적으로 이 상태 코드를 보고 요청이 잘 처리되었는지 문제가 있는지 알 수가 있습니다.패키지 설치
응답 상태
상태 코드는 응답 객체의 status_code 속성을 통해 간단하게 얻을 수 있습니다.
>>> response = requests.get("//jsonplaceholder.typicode.com/users/1") >>> response.status_code 200 >>> response = requests.get("//jsonplaceholder.typicode.com/users/100") >>> response.status_code 404 >>> response = requests.post("//jsonplaceholder.typicode.com/users") >>> response.status_code 201
응답 전문
요청이 정상적으로 처리가 된 경우, 응답 전문(response body/payload)에 요청한 데이터가 담겨져 옵니다. 응답 전문은 크게 3가지 방식으로 읽어올 수 있습니다.
>>> response = requests.get("//jsonplaceholder.typicode.com/users/1")
첫 번째는 content 속성을 통해 바이너리 원문을 얻을 수 있습니다.
>>> response.content b'{\n "id": 1,\n "name": "Leanne Graham",\n "username": "Bret",\n "email": "",\n "address": {\n "street": "Kulas Light",\n "suite": "Apt. 556",\n "city": "Gwenborough",\n "zipcode": "92998-3874",\n "geo": {\n "lat": "-37.3159",\n "lng": "81.1496"\n }\n },\n "phone": "1-770-736-8031 x56442",\n "website": "hildegard.org",\n "company": {\n "name": "Romaguera-Crona",\n "catchPhrase": "Multi-layered client-server neural-net",\n "bs": "harness real-time e-markets"\n }\n}'
두 번째는 text 속성을 통해 UTF-8로 인코딩된 문자열을 얻을 수 있습니다.
>>> response.text '{\n "id": 1,\n "name": "Leanne Graham",\n "username": "Bret",\n "email": "",\n "address": {\n "street": "Kulas Light",\n "suite": "Apt. 556",\n "city": "Gwenborough",\n "zipcode": "92998-3874",\n "geo": {\n "lat": "-37.3159",\n "lng": "81.1496"\n }\n },\n "phone": "1-770-736-8031 x56442",\n "website": "hildegard.org",\n "company": {\n "name": "Romaguera-Crona",\n "catchPhrase": "Multi-layered client-server neural-net",\n "bs": "harness real-time e-markets"\n }\n}'
마지막으로, 응답 데이터가 JSON 포멧이라면 json() 함수를 통해 사전(dictionary) 객체를 얻을 수 있습니다.
>>> response.json() {'id': 1, 'name': 'Leanne Graham', 'username': 'Bret', 'email': '', 'address': {'street': 'Kulas Light', 'suite': 'Apt. 556', 'city': 'Gwenborough', 'zipcode': '92998-3874', 'geo': {'lat': '-37.3159', 'lng': '81.1496'}}, 'phone': '1-770-736-8031 x56442', 'website': 'hildegard.org', 'company': {'name': 'Romaguera-Crona', 'catchPhrase': 'Multi-layered client-server neural-net', 'bs': 'harness real-time e-markets'}}
응답 헤더
응답에 대한 메타 데이터를 담고 있는 응답 헤더는 headers 속성을 통해 사전의 형태로 얻을 수 있습니다.
>>> response = requests.get("//jsonplaceholder.typicode.com/users/1") >>> response.headers {'Date': 'Sat, 12 Dec 2020 21:10:49 GMT', 'Content-Type': 'application/json; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Set-Cookie': '__cfduid=d92df672c0d58b06b245dd0b8d317e2141607807449; expires=Mon, 11-Jan-21 21:10:49 GMT; path=/; domain=.typicode.com; HttpOnly; SameSite=Lax', 'X-Powered-By': 'Express', 'X-Ratelimit-Limit': '1000', 'X-Ratelimit-Remaining': '999', 'X-Ratelimit-Reset': '1607798104', 'Vary': 'Origin, Accept-Encoding', 'Access-Control-Allow-Credentials': 'true', 'Cache-Control': 'max-age=43200', 'Pragma': 'no-cache', 'Expires': '-1', 'X-Content-Type-Options': 'nosniff', 'Etag': 'W/"1fd-+2Y3G3w049iSZtw5t1mzSnunngE"', 'Via': '1.1 vegur', 'CF-Cache-Status': 'HIT', 'Age': '9352', 'cf-request-id': '06fa63d142000038668b9a7000000001', 'Expect-CT': 'max-age=604800, report-uri="//report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"', 'Report-To': '{"endpoints":[{"url":"\\/\\/a.nel.cloudflare.com\\/report?s=Vk2e8Q%2FBK4wOSQc12Cgs0nqvZHpyUb4c0o%2BWCgLzwdqPLQM2HJ5hNHW%2Fmc8fNr73wqQ2LrzEdScfv5bejTYVrXRlUfAyPcGnv1me%2BHlZKc7IKKOi%2BO%2ButGVrdkWS"}],"group":"cf-nel","max_age":604800}', 'NEL': '{"report_to":"cf-nel","max_age":604800}', 'Server': 'cloudflare', 'CF-RAY': '600a6f2edfe23866-IAD', 'Content-Encoding': 'gzip'} >>> response.headers['Content-Type'] 'application/json; charset=utf-8'
요청 쿼리
GET 방식으로 HTTP 요청을 할 때는 쿼리 스트링(query string)을 통해 응답받을 데이터를 필터링하는 경우가 많습니다.
params 옵션을 사용하면 쿼리 스크링을 사전의 형태로 넘길 수 있습니다.
# //jsonplaceholder.typicode.com/posts?userId=1 >>> response = requests.get("//jsonplaceholder.typicode.com/posts", params={"userId": "1"}) >>> [post["id"] for post in response.json()] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
요청 전문
POST나 PUT 방식으로 HTTP 요청을 할 때는 보통 요청 전문(request body/payload)에 데이터를 담아서 보내는데요.
data 옵션을 사용하면, HTML 양식(form) 포멧의 데이터를 전송할 수 있으며, 이 때 Content-Type 요청 헤더는 application/x-www-form-urlencoded로 자동 설정됩니다.
>>> requests.post("//jsonplaceholder.typicode.com/users", data={'name': 'Test User'}) <Response [201]>
json 옵션을 사용하면, REST API로 JSON 포멧의 데이터를 전송할 수 있으며, 이 때 Content-Type 요청 헤더는 application/json로 자동 설정됩니다.
>>> requests.post("//jsonplaceholder.typicode.com/users", json={'name': 'Test User'}) <Response [201]>
요청 헤더
headers 옵션을 사용하면 요청 헤더도 직접 설정할 수 있는데요. 인증 토큰을 보낼 때 유용하게 사용할 수 있습니다.
>>> requests.post("//jsonplaceholder.typicode.com/users", headers={'Authorization': 'Bearer 12345'}) <Response [201]>
전체 코드
본 포스팅에서 제가 작성한 코드는 아래에서 직접 확인하고 실행해보실 수 있습니다.
//dales.link/wxd
마치면서
이상으로 파이썬의 requests 라이브러리의 기본적인 사용 방법을 살펴보았습니다. 파이썬에 내장된 모듈은 아니지만 HTTP 호출을 할 때 거의 표준처럼 사용되는 라이브러리이기 때문에 사용법을 잘 숙지해두시면 큰 도움이 되실 겁니다.