[Django]
알아두기!
웹 서버와 클라이언트는 HTTP 프로토콜을 사용하여 통신함
HTTP 응답은 상태줄(status line), 헤더(header), 빈 줄(blank line), 본문(body) 으로 옴
상태줄 | HTTP 버전, 상태코드, 상태메세지 |
헤더 | 응답에 대한 추가 정보, key:value |
빈 줄 | 헤더와 본문 사이에 위치, HTTP 요청의 끝을 나타냄, 빈줄이 있어야 헤더의 끝과 본문의 시작을 알 수 있음 |
본문 | 실제 데이터 |
String에서는 null('\0') 문자의 끝을 나타내고
HTTP 통신에서는 빈 줄('\n')이 요청의 끝을 나타내는 것
웹 클라이언트 라이브러리
requests (객체)
파이썬에서 HTTP요청을 보내고 응답을 처리하기 위한 라이브러리
- 간결하고 사용하기 쉬운 API :
HTTP 요청을 보내고 응답을 처리하는 것을 쉽게 만들어줌
GET, POST, PUT, DELETE 등의 다양한 메서드를 지원함
- 파라미터 전달 :
requests를 사용하여 URL에 쿼리 문자열 형태로 파라미터를 전달할 수 있음
>> requests.get( url, params={'key' : 'Value'} )
- 요청 헤더 설정 :
requests를 사용하여 요청 헤더에 필요한 정보(인증, 권한, 사용자에이전트(User-Agent) 등)를 추가할 수 있음
- 응답 처리 :
requests로 받은 응답 객체(Response Object)에서 상태코드 헤더 본문 등의 정보에 접근할 수 있음
- 세션 관리 :
requests.Session 클래스를 사용하여 세션을 유지하고 요천 간의 쿠키와 같은 정보를 공유할 수 있음
- 파일 업로드 및 다운로드 :
multipart / form-data 형식으로 파일을 업로드 하거나 바이너리 데이터를 다운로드 하는 등의 작업을 할 수 있음
- HTTPS 지원과 SSL 인증서 검증 :
requests는 HTTPS 프로토콜을 지원하며, SSL인증서 검증 기능도 제공함
from urllib.request import urlopen
from html.parser import HTMLParser
class ImagePerser(HTMLParser):
def __init__(self):
super().__init__()
self.result = []
def handle_starttag(self, tag, attrs): # <tag>를 처리하기 위해 오버라이딩한거
if tag != 'img' : # 이미지가 아닐 때
return
if not hasattr(self, 'result'): # 결과가 없을 때
self.result = []
for name, value in attrs:
if name == 'src': # 이미지 경로만 뽑아오려고
self.result.append(value)
def parseImage(data): # 객체 생성
parser = ImagePerser()
parser.feed(data)
dataSet = set(x for x in parser.result) # set인 이유: 중복 불가능하게 만드려고
return dataSet
def main():
url = "http://www.google.co.kr"
f = urlopen(url)
charset = f.info().get_param('charset')
data = f.read().decode(charset)
f.close()
dataSet = parseImage(data)
print("\n>>>>>> Fetch Images from", url) #1
print(dataSet) #2
print('\n'.join(sorted(dataSet))) #3
if __name__ == '__main__':
main()
▼ 결과 ▼
#1)
>>>>>> Fetch Images from http://www.google.co.kr
#2)
{'/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png', '/textinputassistant/tia.png'}
#3)
/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png
/textinputassistant/tia.png
www.google.co.kr
urllib
파이썬 표준 라이브러리
URL 작업과 관련된 다양한 모듈 제공
- urllib.request 모듈 :
HTTP 요청을 보내고 응답을 처리하는 기능 제공
urlopen() 함수를 사용하여 URL에 대한 GET 요청을 보낼 수 있음
request 클래스를 사용하여 더 많은 컨트롤, 구성 옵션 등을 설정할 수 있음
응답받은 객체(ex: 위 예시에 dataSet)는 파일 객체와 유사한 인터페이스를 가지며, 상태 코드, 헤더, 본문 등의 정보에 접근할 수 있음
- urllib.parse 모듈 :
URL 구문 분석 및 조작에 사용
urlparse() 함수를 사용하여 URL 문자열을 구성요소(호스트, 스킴, 경로 등)로 분석할 수 있음
urlunparse() 함수를 사용하여 구성요소로부터 URL 문자열을 생성할 수 있음
쿼리 문자열 파싱 및 조작 기능(parse_qs(), urlencode())도 제공함
http.client
파이썬 표준 라이브러리에 포함된 HTTP 클라이언트 라이브러리
- HTTP 요청 보내기 :
http.client.HTTPConnection 클래스를 사용하여 서버와의 연결을 설정함
request() 메서드를 사용하여 GET, POST, PUT, DELETE 등의 메서드로 HTTP 요청을 보낼 수 있음
헤더와 본문 데이터를 설정할 수 있음
- 응답처리 :
getresponse() 메서드를 호출하여 서버로 부터 받은 응답 객체(Response Object)를 가져옴
응답받은 객체(ex: 위 예시에 dataSet)는 파일 객체와 유사한 인터페이스를 가지며, 상태 코드, 헤더, 본문 등의 정보에 접근할 수 있음
- 세션관리 :
http.client.HTTPSConnection 클래스는 HTTPS 프로토콜을 지원하는 버전
SSL/TLS 연결 시 서버의 인증서가 신뢰할 수 있는지 확인하거나 인증서 설정 등의 작업을 할 수 있음
- 예외처리 :
네트워크 오류나 잘못된 요청 등이 발생 가능한 상황에서 예외처리를 할 수 있음
>> 주요 예외로 http.client.HTTPException 을 사용해서
from pathlib import Path
from http.client import HTTPConnection
from urllib.parse import urljoin, urlunparse
from urllib.request import urlretrieve
from html.parser import HTMLParser
class ImagePerser(HTMLParser):
def handle_starttag(self, tag, attrs):
if tag != 'img' :
return
if not hasattr(self, 'result'):
self.result = []
for name, value in attrs:
if name == 'src':
self.result.append(value)
def downloadImage(url, data):
downDir = Path("DOWNLOAD")
downDir.mkdir(exist_ok=True)
parser = ImagePerser()
parser.feed(data)
dataSet = set(x for x in parser.result)
for x in sorted(dataSet):
imageUrl = urljoin(url, x)
basename = Path(imageUrl).name
targetFile = downDir / basename
print("Downloading...", imageUrl)
urlretrieve(imageUrl, targetFile)
def main():
host = "www.google.co.kr"
conn = HTTPConnection(host)
conn.request("GET", '')
resp = conn.getresponse()
charset = resp.msg.get_param('charset')
data = resp.read().decode(charset)
conn.close()
print("\n >>>>>>>>>>> Download Image from ", host) #1
url = urlunparse(("http", host, '', '', '', ''))
downloadImage(url,data) #2
if __name__ == '__main__':
main()
▼ 결과 ▼
#1)
>>>>>>>>>>> Download Image from www.google.co.kr
#2)
Downloading... http://www.google.co.kr/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png
Downloading... http://www.google.co.kr/textinputassistant/tia.png
www.google.co.kr
Django 내장 웹 클라이언트
django.test.Client 클래스를 사용하여 Django 어플리케이션 내에서 테스트 및 시뮬레이션 목적으로 HTTP 요청을 만들 수 있음
주로 테스트 프레임 워크에서 사용되지만, 일반적인 웹 클라이언트로서도 활용할 수 있음
- HTTP 요청 보내기
get(), post(), put(), delete() 등의 메서드를 사용하여 HTTP 요청을 보낼 수 있음
필요한 경우 URL, 데이터, 헤더 등을 지정할 수 있음
- 응답처리
해당하는 HTTP 응답 객체를 반환함
- 세션 유지
한번 연결된 세션을 유지하고 여러 요청에 대해 동일한 세션 상태를 유지할 수 있음
- 폼 처리
post() 메서드를 사용하여 데이터를 제출 할 수 있음
>> 실제 브라우저 제출과 비슷한 동작을 함
웹 서버 라이브러리
http.server 모듈에 포함되어 있는 클래스
- HTTPServer
http.server.HttpServer
기본적인 HTTP 서버를 구현하는데 사용됨
TCP 소켓을 생성하고 요청을 수신하기 위해 지정된 IP 주소와 포트에 대기함
요청이 들어오면 해당 요청을 처리할 핸들러 객체(BaseHTTPRequestHandler의 인스턴스)를 생성하여 처리
- BaseHTTPRequestHandler
http.server.BaseHTTPRequestHandler
HPPT 요청을 처리하는 핵심 로직을 구현하는 추상클래스
실제로 사용하기 위해서는 해당 클래스를 상속 받아서 사용자 정의 핸들러 클래스를 작성해야 함
- 주요 메서드
do_GET() : GET 요청에 대한 처리 로직을 구현
do_POST() : POST 요청에 대한 처리 로직을 구현
send_response() : 응답 상태 코드와 헤더 정보를 전송
send_header() : 응답 헤더 정보 전송
end_header() : 응답 헤더의 끝임을 알리는 빈 줄(CRLF)을 전송
▶ 예시
from http.server import HTTPServer, BaseHTTPRequestHandler
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response_only(200, 'OK')
self.send_header('Connect-Type', 'text/plain')
self.end_headers()
self.wfile.write(b"Hello World")
if __name__ == "__main__":
server = HTTPServer(('', 8888), MyHandler)
print("Started Webserver on port 8888....")
print("Press ^C to quit Webserver.")
server.serve_forever()
- SimpleHTTPRequestHandler
정적 파일을 제공하기 위한 간단한 HTTP요청 처리기
>> 주로 개발 및 테스트용
SimpleHTTPRequestHandler는 BaseHTTPRequestHandler를 상속함
>> 기본 메서드들을 상속받아 정적 파일 서비스를 처리하는 추가 로직을 구현함
1) 정적 파일 서비스
현재 작업 디렉토리에서 정적 파일(HTML, CSS, JavaScript, 이미지 등)을 제공
GET 요청에 대해 요청된 파일이 존재하는 경우 해당 파일을 응답으로 보냄
2) Content-Type 자동 설정
요청된 파일의 확장자를 기반으로 Content-Type의 헤더 값을 자동으로 설정함
>> .html → /text/html
>> .jpg → /image/jpg
3) Range 지원
Range 요청 헤더가 있는 경우 해당 범위 만큼의 데이터만 응답으로 보낼 수 있음
>> 다운로드 중 일부만 필요한 경우 → 대용량 파일 전송, 스트리밍과 같은 상황에서 유용함
▶ 예시
- CGIHTTPRequestHandler
>> CGI : Common Gateway Interface
CGI는 웹 서버와 외부 프로그램 간의 표준 인터페이스를 제공하여 동적인 웹 콘텐츠를 생성하는데 사용
CGIHTTPRequestHandler는 CGI 프로그램을 실행하고 처리하기 위해 사용
CGIHTTPRequestHandler는 BaseHTTPRequestHandler를 상속함
CGI 스크립트를 실행하기 위한 추가 로직을 작성함
1) CGI 스크립트 실행
CGIHTTPRequestHandler는 클라이언트가 요청한 CGI 스크립트를 실행함
GET, POST 요청에 대한 환경변수와 데이터(playloda)를 설정하여 스트립트를 호출
스크립트의 실행 결과가 HTTP 응답으로 반환됨
2) 환경변수
요청메서드, URL경로, 쿼리 문자열 등과 같은 정보가 환경변수로 설정되어 CGI 스크립트에서 참조할 수 있음
이러한 환경 변수들은 on.environ 딕셔너리에 저장되어 전달됨
3) 보안검사
기본적으로 CGIHTTPRequestHandler는 보안검사를 수행하여 악성코드나 디렉토리 트래버셜 공격을 방지
경로 검사, 접근 제어 등의 기본적인 보안 기능도 있음
500 Internal Error 오류 발생 시 내장된 오류페이지를 출력