달나라 노트

Python requests : GET/POST 방식 요청, API 사용, curl, requests 본문

Python/Python ETC

Python requests : GET/POST 방식 요청, API 사용, curl, requests

CosmosProject 2023. 9. 13. 19:42
728x90
반응형

 

 

 

이번에는 URL과 URL을 통한 요청 그리고 GET, POST 등의 방식에 대해 그냥 매우 간단하고 알기 쉽게 알아볼겁니다.

(그냥 단순히 컨셉을 이해하는게 목표이므로 그 내부에 숨겨진 정말 자세한 내용까지는 다루지 않습니다.)

 

 

 

우리가 URL을 통해 서버에 뭔가를 요청하면 서버는 그에 대한 답을 줍니다.

서버로부터 오는 답이 보통 HTML 형태의 데이터이고, 우리는 HTML 코드를 보기좋게 해석해서 표시해주는 웹 브라우저가 있죠.

 

그래서 웹 브라우저에 우리가 URL을 입력하면 그 요청을 받은 서버는 요청에 대한 결과를 웹 브라우저에 전송합니다.

웹 브라우저는 서버로부터 전송받은 HTML 코드를 유저가 보기 좋게 해석해서 표시해주게되죠.

 

 

내가 어떤 쇼핑몰을 들어간다고 해봅시다.

쇼핑몰의 URL은 아래와 같다고 가정해봅시다.

https://www.test_shopping.com 

 

보통 이 쇼핑몰에 진입하려면 이 URL을 브라우저에 입력하겠죠. (물론 해당 URL을 북마크해두어서 북마크를 클릭할 수도 있지만 결국 URL을 입력하는 것과 동일합니다.)

 

보통 위같은 URL을 입력하면 해당 쇼핑몰의 메인 페이지가 뜰겁니다.

 

 

 

근데 저희가 쇼핑몰을 들어가는 이유는 단순히 쇼핑몰의 메인 페이지를 보기 위해서가 아니죠.

내가 원하는 상품을 찾고, 그 상품 페이지에 들어가서 상품을 구매하기 위함일 것입니다.

사실 쇼핑몰의 메인 페이지보다 더 많은 부수적인 내용들이 필요합니다.

 

만약 우리가 어떤 쇼핑몰에서 판매하는 특정 상품 페이지에 접근하려면 어떻게 해야할까요?

 

주로 쓰이는 방법은 아래와 같습니다.

https://www.test_shopping.com?item_id=111&color=blue

 

뭔가 URL 뒷부분에 ?가 붙고 그 뒤로 어떤 내용이 더 붙었습니다.

위 URL을 해석해보면 다음과 같습니다.

 

https://www.test_shopping.com -> 이 쇼핑몰의 홈페이지에서

? -> 내가 특정 조건을 부여할건데

item_id=111&color=blue -> item_id가 111 이고, color가 blue인 상품의 페이지를 띄워줘.

 

라는 의미입니다.

 

즉, URL 뒷부분에 내가 원하는 상품에 대한 조건을 서버에 전달해서 서버로부터 그 상품 페이지에 대한 HTML 코드를 받아오는 것이죠.

그러면 우리 웹 브라우저에는 item_id가 111이고 color가 blue인 상품의 페이지가 띄워질겁니다.

 

이렇게 URL 뒤에 ?를 붙이고 특정 조건(query)을 전달하는 방식을 GET 방식이라고 합니다.

 

GET 방식은 내가 부여한 부수적인 조건들이 URL에 모두 보이는 것이 특징입니다.

 

 

 

반대로 POST 방식도 있습니다.

POST 방식은 GET 방식처럼 URL에 내가 원하는 조건을 담아서 전달하지 않습니다.

POST 방식은 html의 header나 body에 원하는 내용을 담아서 전달합니다.

 

<html>
    <head>
        ~~~
    </head>

    <body>
        ~~~
    </body>
</html>

html의 구조를 보면 보통 위와 같습니다.

 

head tag 사이에는 메타데이터, 즉, 사용자의 눈에 보이지는 않는 여러 설정값들이 들어가게 됩니다.

body tag 사이에는 주로 사용자에게 직접 보이는 내용(e.g. 홈페이지의 구성요소, 이미지, 글 등등)들이 들어갑니다.

 

POST 방식은 내가 서버에 요청할 때 붙여야 할 원하는 조건을 head, body 태그에 담아서 요청합니다.

 

그래서 POST 방식은 내가 붙인 조건들이 한눈에 보이지 않는다는 특징이 있습니다.

 

 

 

 

 

GET 방식은 URL 뒤에 ?를 붙이고 내가 원하는 조건을 넣으면 되는데 POST 방식을 사용하게 되면 어떻게 요청을 해야할까요?

 

다양한 방법이 있습니다만 대표적인 2가지 방법을 알아봅시다.

 

 

첫 번째는 curl을 사용하는 것입니다.

curl은 Client URL의 약자로 terminal 같은 command line이나 코드에서 URL을 가지고 할 수 있는 여러 행동들을 할 수 있도록 해주는 것입니다.

 

 

 

curl --location 'https://www.naver.com'

teminal에 위 command를 입력해봅시다.

뭔가 엄청나게 출력될겁니다.

 

curl을 이용하여 www.naver.com이라는 URL을 요청한 그 결과 HTML 코드가 return된 것입니다.

 

 

 

 

 

curl --location 'https://search.naver.com/search.naver?query=apple'

위 command는 naver에서 apple이라는 단어를 검색한 결과를 나타내주는 URL입니다.

GET 방식을 사용하였습니다.

 

 

 

curl --location 'https://www.test_page.com' \
--header 'auth: egs102fisj19md' \
--header 'type: json' \
--data '{
    "key1": [
        {
            "item_id": 111,
            "color": "blue"
        },
        {
            "item_id": 222,
            "size": "m"
        }
    ]
}'

curl은 위처럼 header, data 같이 여러 옵션을 가지고 있습니다.

이 옵션들을 이용해 POST 방식으로 URL을 요청할 수 있습니다.

 

--header 옵션을 통하면 html 구조에서 header tag 사이에 내가 원하는 내용들을 추가해서 URL 요청을 할 수 있습니다.

 

--data 옵션을 통해 필요한 여러 데이터들을 전달할 수 있습니다.

 

특히나 이런 형태의 요청은 API를 호출할 때 많이 사용됩니다.

 

header, data 옵션에 어떤 형태의 데이터를 입력해야 하는지는 사용하는 URL이나 API에 따라 달라집니다.

 

 

 

 

 

두번째는 python의 requests library를 이용하는 겁니다.

 

import requests

url = 'https://www.naver.com'

result = requests.get(url=url)
print(result.status_code)
print(result.content)

 

- requests.get() -> get() method는 어떤 url을 GET 방식으로 요청하겠다는 의미입니다.

 

위 코드를 실행시키면 https://www.naver.com 이라는 url을 GET 방식으로 요청하게 되며, 큰 문제가 없는 한 status_code는 200이 출력될겁니다.

url에 대한 요청과 그 결과를 받아오는 과정이 정상적으로 실행됐다는 의미입니다.

 

그리고 content attribute에는 서버에서 준 그 결과가 bytes type의 형태로 return될겁니다.

(b'~~~' 이렇게 따옴표 앞에 b가 붙으면 따옴표 내부에 있는 데이터는 bytes 타입의 데이터라는 의미입니다.)

 

 

 

 

import requests

url = 'https://search.naver.com/search.naver?query=apple'

result = requests.get(url=url)
print(result.content)

위 코드를 실행하면 아까 curl을 이용했던 것 처럼 naver에서 apple이라는 글자를 검색한 결과 페이지의 HTML 코드가 return될겁니다.

 

 

그런데 만약 get method로 요청을 할 때 query에 추가해야 할 조건이 많다면 어떻게될까요?

 

https://www.test_shopping.com?item_id=111&color=blue&size=M&discount=Y

 

조건이 여러개라면 위처럼 계속 &로 연결하여 URL을 길게 만들면 됩니다.

다만 이렇게 될 경우 조건이 많아질수록 URL의 가독성도 떨어지고, 어떤 조건이 있는지도 한눈에 보기 어렵습니다.

즉, URL을 만들다가 오류가 발생할 가능성이 크죠.

 

이럴 때에는 params라는 유용한 옵션을 사용할 수 있습니다.

 

 

import requests

url = 'https://www.test_shopping.com'

params = {
    'item_id': '111',
    'color': 'blue',
    'size': 'M',
    'discount': 'Y',
}

result = requests.get(url=url, params=params)
print(result.content)

 

params 옵션은 dictionary를 전달해야하며

dictionary는 URL에 사용될 조건들이 들어가있습니다.

 

URL에는 그냥 기본 주소만 적어두고,

params 옵션에 어떠한 조건들을 적용할건지 넣어두고 params 옵션으로 전달하면 되는것이죠.

 

이렇게하면 GET method를 통해 URL 요청을 할 때 일일이 모든 조건을 넣어서 URL을 구성하지 않아도 되는 장점이 있습니다.

 

 

 

 

 

import requests


url = 'https://www.test_page.com'
headers = {
    'auth': 'egs102fisj19md',
    'type': 'json',
}
json_data = {
    "key1": [
        {
            "item_id": 111,
            "color": "blue"
        },
        {
            "item_id": 222,
            "size": "m"
        }
    ]
}

result = requests.post(url=url,
                       headers=headers,
                       json=json_data)

requests 모듈도 당연히 POST 방식을 지원합니다.

 

위처럼 requests.post() method를 이용하면 됩니다.

 

 

result = requests.post(url=url,
                       headers=headers,
                       json=json_data)

그리고 POST 방식으로 요청할 때 header에 전달할 내용, data에 전달할 내용, json에 전달할 내용 등을 담을 때에는 post() method에 있는 parameter들을 이용하면 됩니다.

 

post() method에는 다양한 parameter가 있으며 이는 아마 구글링을 하면 필요한 내용이 뭔지 알 수 있을겁니다.

 

 

 

 

 

 

 

 

 

 

curl --location 'https://www.test_page.com' \
--header 'auth: egs102fisj19md' \
--header 'type: json' \
--data '{
    "key1": [
        {
            "item_id": 111,
            "color": "blue"
        },
        {
            "item_id": 222,
            "size": "m"
        }
    ]
}'

 

import requests


url = 'https://www.test_page.com'
headers = {
    'auth': 'egs102fisj19md',
    'type': 'json',
}
json_data = {
    "key1": [
        {
            "item_id": 111,
            "color": "blue"
        },
        {
            "item_id": 222,
            "size": "m"
        }
    ]
}

result = requests.post(url=url,
                       headers=headers,
                       json=json_data)

 

지금까지 본 예시 2가지를 다시 봐봅시다.

위 2개의 예시는 curl을 이용하는지, python을 이용하는지의 차이만 있을 뿐 완전히 동일한 동작과 결과를 가져옵니다.

 

다만 curl 명령어를 python의 형태로 그대로 쓸 순 없죠. 그 반대도 마찬가지이구요.

 

이때 curl command를 python의 requests library등 다양한 환경에서 이용가능한 코드로 변환해주는 아주 유용한 사이트가 있습니다.

 

https://curlconverter.com 

 

Convert curl commands to code

GitHub is matching all contributions to this project on GitHub Sponsors. Contribute Now

curlconverter.com

 

 

 

curlconverter 사이트에서 curl 명령어를 입력하면 우리가 원하는 프로그래밍 언어 하에서 사용할 수 있는 형태로 변경해줍니다.

 

 

 

 

 

 

728x90
반응형
Comments