[Python] HTTP GET으로 request 보내 받기

2024. 11. 11. 22:41Developers 공간 [Shorts]/Software Basic

728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew, 
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter

- Module Bundler  : React, Webpack, Parcel

B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS

C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight

 


1. What? (현상)

 

보통 HTTP Methods(GET, POST, PUT, PATCH, DELETE) 중 GET을 활용해 content를 파일로 저장하는 경우 CLI에서 아래와 같이 curl을 활용하거나,

curl -w '%{http_code}\n' \
		-o output.file \
        --location ‘http://abc.com/external/api/v1.0?aName=AAA&bName=BBB&cName=CCC' \
        --header “dName: DDD”

 

wget을 활용하는 것이 가장 간단한 방법일 것입니다.

wget --header="dName:DDD" \
	“http://abc.com/external/api/v1.0?aName=AAA&bName=BBB&cName=CCC" \
    -O output.file

 

하지만 이번 글에서는 Python을 활용해 request를 보내는 방법을 정리하고자 합니다.

 

먼저 상황은 위에서 요청한 것과 같이 정리할 수 있습니다.

  • API를 제공할 서버의 URL : http://abc.com/external/api/v1.0
  • Query Parameter
    ** Query Parameter : URL 뒤에 정보 요청의 필터링을 위해 사용됩니다. (물음표(?) 이후에 나오며, 키-값(Key-Value) 쌍으로 이루어지고, 앰퍼샌드(&)로 연결됩니다.)
    ** Query Parameter 예시 : http://www.example.com/resources?name1=value1&name2=value2
    • aName= AAA
    • bName= BBB
    • cName= CCC
  • Header
    • dName : DDD
  • 정보를 저장할 파일 : output.file

2. Why? (원인)

  • X

3. How? (해결책)

 

먼저, request와 header로 정리하면 아래와 같을 것입니다. 

aName="AAA"
bName="BBB"
cName="CCC"
dName="DDD"

request_go=f"https://abc.com/external/api/v1.0?aName={aName}&bName={bName}&cName={cName}"

header_go={
    'dName' : dName
}

 

그럼 이제 HTTP를 활용해 요청할 3가지 방법에 대해 소개하겠습니다.

 

방법1. urllib

import urllib.request
req = urllib.request.Request(request_go, headers=header_go)
contents = urllib.request.urlopen(req).read()
print(contents)

 

방법2. httplib2

import httplib2
h = httplib2.Http()
resp, content = h.request(request_go, 'GET', headers=header_go)
print("resp : {}".format(resp))
print("content : {}".format(content))

 

방법3. requests (선호)

import requests
r = requests.get(request_go, headers=header_go)
print("status : {}".format(r.status_code))
print("headers : {}".format(r.headers))
print("encoding : {}".format(r.encoding))
print("contents : {}".format(r.content))  # bytes
print("text : {}".format(r.text))     # r.content as str

 

 

그럼 위 방법3으로 얻었을 때를 예로, content를 파일로 저장하려면 어떻게하면 좋을까요?

 

먼저 아래와 같이 header의 "Content Disposition"에서 파일의 이름을 알아냅니다. 보통 아래와 같은 포맷으로 header에 존재합니다.

Content-Disposition: attachment; filename="filename.jpg"
if r.status_code==200:
	print(“success”)

_, name = r.headers['Content-Disposition'].split('; ')
if name.startswith('filename='):
    from urllib.parse import unquote
    filename = unquote(name.strip().split('=')[-1]).strip('\"')
else:
    raise Exception("[Error] filename is not included : {}".format(name))
print("\n\n file name is {}".format(filename))

 

그다음 해당 파일의 이름으로 content를 저장합니다.

with open(filename, 'wb') as file:
    file.write(r.content)

 

728x90
반응형