반원 블로그

6. requests 모듈 - REST API 사용법, curl을 python requests로 변환방법 본문

2018~/Python Skill Up

6. requests 모듈 - REST API 사용법, curl을 python requests로 변환방법

반원_SemiCircle 2019. 9. 6. 10:26

개요

파이썬 공식에서도 인정한 인간친화적인 웹 요청 모듈인 requests의 사용법을 터득해, 웹 요청-응답 과정을 이해하고, REST API를 원활하게 사용해보자.
requests 모듈 문서
requests 유저 가이드
requests api 레퍼런스 문서

설치

  • pip3 install requests

자주 같이 사용하는 모듈 및 패키지

  • requests
  • json
  • pprint
  • bs4

HTTP 메소드에 따른 요청 - 기초

GET, POST, PUT 등의 방식을 지정하여 웹 요청을 해야할 때 다음처럼 코드를 작성하면된다.
POST와 PUT의 경우는 보통 데이터 생성과 수정을 일으키는 HTTP 메소드므로 기본 예제에서도 data 매개변수가 나와있다.

여기서 r은 응답데이터(response)에서 앞 문자만 따왔다.

import requests
r = requests.get('https://api.github.com/events')
r = requests.post('https://httpbin.org/post', data = {'key':'value'})
r = requests.put('https://httpbin.org/put', data = {'key':'value'})
r = requests.delete('https://httpbin.org/delete')
r = requests.head('https://httpbin.org/get')
r = requests.options('https://httpbin.org/get')

웹 요청시 매개변수 전달방법

GET 요청 기준으로 URL은
HOST + PATH ? Paremeter1=value1&Parameter2=value2... 형식으로 되있다.
문자열로 이를 직접 매개변수 영역을 적어도되나 get아닌 다른 방식에서는 사용할 수 없다.

requests는 매개변수 전달을 하는 방식을 이렇게 안내한다.

payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('https://httpbin.org/get', params=payload)

만일 네이버에서 아이스크림을 검색하는 url 요청을 한다고하면 다음과 같이 된다.

import requests

#웹 요청 방식 - 정식
#https://search.naver.com/search.naver?query=아이스크림  의 경우
host = 'https://search.naver.com'
path = '/search.naver'
params = {'query':'아이스크림'}

url = host + path
response = requests.get(url,params=params)

응답 데이터의 속성들

웹 요청을 하여 돌아온 데이터를 응답 데이터(response data)라고 하자.
이 응답 데이터에는 여러가지 속성과 메소드가 들어있다. [참고]

# 응답 데이터의 속성들
print(response.status_code) #응답 상태 코드
print(response.url) #요청했던 url
print(response.text) #응답데이터(str) - 주로 웹 페이지 소스코드나 문자 데이터 or json을 확인할 때
print(response.content) #응답데이터(byte) - 주로 음악, 비디오등 byte 자체를 받아 저장시킬 때 사용
print(response.encoding) #응답데이터의 인코딩 방식
print(response.headers) #응답데이터의 헤더

응답 데이터의 메소드

응답 데이터가 json일 경우에는 굳이 import json의 dumps 함수를 쓰지 않아도 바로 변환 가능하낟.

data = response.json()

응답 데이터의 상태코드를 확인하려면 response.status_code를 하여 각 상황에 맞게 코드를 작성할 수 있는데,
response.raise_for_status()메소드를 이용하면 http error가 생겼을 때(4xx,5xx) 오류를 발생시킬수 있다.

data = response.raise_for_status()

웹 요청 데이터의 HEADER 변경

특정 사이트의 경우, 웹 브라우저를 이용한 접속시에 '봇(BOT)'으로 감지하여 제대로된 응답데이터를 안돌려주는 경우가 있다.
이 때 HEADER를 따로 생성함으로써 해결할 수 있는데 기본 가이드는 다음과 같다.

url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get(url, headers=headers)

user-agent의 값을 내가 원하는 브라우저로 지정해주면 되는데, 웹 브라우저에서 지원하는 개발자 도구를 통해 이를 확인할 수도 있다. 다음은 대체로 많이 사용하는 헤더 예시이다.

import requests

url = 'http://www.ichangtou.com/#company:data_000008.html'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

response = requests.get(url, headers=headers)
print(response.content)

POST 방식으로 요청

POST 방식으로 요청할 때 대부분 클라이언트 측에서 데이터를 전송한다. 그 데이터가 단순 객체(변수 값 등)이 될 수도, 파일이 될 수도 있다.

단순 객체를 보낼대는 data 매개변수를 사용한다.

data = {'key':'value'}
r = requests.post('https://httpbin.org/post', data = data )

특정 파일을 같이 보내는 POST의 경우 예시는 다음과 같다.(얼굴 인식 rest api 등)
open 함수를 통해 해당 파일을 binary 형태로 데이터를 불러온 뒤, 실질적 웹 요청때 files 매개변수에 넣어준다.
여러 개의 파일 전송이 필요한 경우는 다음을 참고하자. 링크

url = 'https://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}
r = requests.post(url, files=files)

한편 딕셔너리(dict)형 데이터를 전달해야할 때 json으로 변환하여 전달해야했다.(기존)

import json
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
r = requests.post(url, data=json.dumps(payload))

그런데 현재는 json 매개변수가 따로 생겨서 그냥 딕셔너리(dict)를 넣으면 위와 같은 기능을 한다.(요즘 많이 쓰이는 방식)

url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
r = requests.post(url, json=payload)

curl 읽는 법

특정 rest api 문서들을 보면 curl 방식으로 가이드되있는 경우가 있다(많다.)
요청시 이에 맞게 파이썬 코드를 작성해줘야하며 주로 다뤄지는 옵션에 대해 꼭 넣어야할 매개변수는 다음과 같다.

  • -d : data 함께 전달할 파라미터값 설정하기
  • -f : files
  • -j : jsons
  • -H : hedears
  • -A : 헤더의 user-agent가 안내
  • -X : 요청시 필요한 메소드 방식 안내
  • -G : 전송할 사이트 url 및 ip 주소
  • -i : 사이트의 Header 정보만 가져오기
  • -I : 사이트의 Header와 바디 정보를 함께 가져오기
  • -u : 사용자 정보

예시1 : 카카오 얼굴 인식 문서(웹 이미지)

curl -v -X POST "https://kapi.kakao.com/v1/vision/face/detect" \
-d "image_url=https://t1.daumcdn.net/alvolo/_vision/openapi/r2/images/01.jpg" \
-H "Authorization: KakaoAK kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"

예시1을 이용하여 파이썬으로 요청 할 때 코드
'''
import requests

url="https://kapi.kakao.com/v1/vision/face/detect"
data = {'image_url':'https://t1.daumcdn.net/alvolo/\_vision/openapi/r2/images/01.jpg'}
header = {'Authorization':'KakaoAK kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk'}

res = requests.post(url, data=data, headers = header)
print(res.status_code)
'''

예시2 : 카카오 얼굴 인식 문서(로컬 이미지)

curl -v -X POST "https://kapi.kakao.com/v1/vision/face/detect" \
-F "file=@sample_face.jpg" \
-H "Authorization: KakaoAK kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"

예시2을 이용하여 파이썬으로 요청 할 때 코드
'''
import requests

url="https://kapi.kakao.com/v1/vision/face/detect"
files= {'file' : open('sample_face.jpg','rb').read() }
header = {'Authorization':'KakaoAK kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk'}

res = requests.post(url, files= files, headers = header)
print(res.status_code)
'''

심화 내용은 다음을 참고
참고1 참고2 참고3 참고4

curl command를 python requests로 변환해주는 사이트

curl 명령어를 해석하기 힘들다면 다음 사이트를 이용해보자. 링크

Comments