본문 바로가기
Programming/Django

[들어가기 전에]파이썬 웹 표준 라이브러리

by owllight 2015. 8. 16.


# 파이썬 웹 라이브러리의 전체적인 구성에 대해 알아본다.
#
웹 클라이언트 라이브러리와 웹 서버 라이브러리의 중요한 모듈에 대해 알아본다.

 

1. 웹 라이브러리 구성

파이썬의 웹 관련 라이브러리는 2.x 버전과 3.x버전에 따라 다르게 구성되어 있다. 둘의 내용은 거의 동일하지만 패키지명과 모듈명이 재구성 되었다.

그림 1-1 웹 표준 라이브러리 구성

# API(Application Programming Interface)
 : 운영체제나 프로그래밍 언어에서 유저가 기능을 손쉽게 사용 할 수 있도록 인터페이스를 제공

그림 1-2 API 이용의 예

>> twittergoogle같은 인터넷 서비스를 제공하는 회사들은 외부 프로그램들이 자신의 서비스를 이용할 수 있도록 openAPI를 제공한다.

2. 웹 클라이언트 라이브러리

파이썬에서는 웹 서버에 정보를 요청할 수 있는 웹 클라이언트를 프로그래밍할 수 있도록 여러 가지 라이브러리를 제공한다. 다양한 라이브러리에 대해 알아보자

from urlparse import urlparse
result = urlparse(
"http://www.naver.com/")
print(result)


urlparse모듈
: URL
의 분해, 조립, 변경 등을 처리하는 함수를 제공한다. 다음 코드는 2.x 버전인 경우이다urlparse()함수는 URL을 파싱한 결과로 ParseResult 인스턴스를 반환한다. ParseResult 클래스 속성의 의미는 다음과 같다.

- scheme : URL에 사용된 프로토콜을 의미
- netloc :
네트워크 위치를 의미, HTTP 프로토콜인 경우는 host:port 형식으로 나타남
- path :
파일이나 애플리케이션 경로를 의미
- params :
애플리케이션에 전달될 매개변수
- query :
질의 문자열로 & 로 구분된 키=값 쌍 형식으로 표시됨
- fragment :
문서 내의 앵커(
anchor) 등 조각을 지정

 

urllib2 모듈
: 이 모듈은 주어진 URL에서 데이터를 가져오는 기본 기능을 제공한다. 가장 기본이 되는 urlopen() 함수의 형식은 urlopen(url, data=None)과 같다. Data는 요청방식으로 디폴트인 경우 GET이다.

from urllib2 import urlopen
f= urlopen(
"http://www.naver.com/") print f.read(500)


POST 방식으로 요청할 경우에는 질의 문자열(query=text)을 지정해주면 된다,


 ! 설명한 내용을 응용하여 실제로 사용할 수 있는 웹 클라이언트를 만들어보자.
: urllib2.urlopen()기능과 추가적으로 HTMLparser 클래스를 사용하여 만들어보자.

from urllib2 import urlopen from HTMLParser import HTMLParser

class  ImageParser(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 parseImage(data):      # HTML문장이 주어지면 Imageparser 클래스를 사용해 이미지를 찾고         parser = ImageParser()           그 리스트를 출력         parser.feed(data)         dataSet = set(x for x in parser.result)         print '\n'.join(sorted(dataSet))
def main():         url = "http://www.naver.com/"         f = urlopen(url)         charset = f.info().getparam('charset')         data = f.read().decode(charset)         f.close()         print "\n  : Fetch images from", url         parseImage(data)
if __name__ == '__main__':     main()


httplib 모듈
: 이 모듈은 urllib2 모듈로는 쉽게 처리할 수 없는 경우에 사용한다. httplib 모듈을 사용하여 웹 클라이언트를 만들 땐 다음과 같은 순서를 기준으로 코딩한다.

import httplib conn = httplib.HTTPConnection("www.naver.com")#주의!! 첫번째 인자는 url이 아닌 host conn.request("GET","/index.html") r1=conn.getresponse() print r1.status, r1.reason data1=r1.read() conn.request("GET", "/parrot.spam") r2=conn.getresponse() print r2.status, r2.reason conn.close()

! 설명한 내용을 응용하여 실제로 사용할 수 있는 웹 클라이언트를 만들어보자.
: 이번에는 urllib2이 아닌 httplib 모듈을 이용하여 특정 웹 사이트에서 이미지만 검색하여 그 이미지들을 다운로드하는 웹 클라이언트를 만들어보자.

import httplib
from urlparse import urljoin, urlunparse
from urllib import urlretrieve
from HTMLParser import HTMLParser
import os

class  ImageParser(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(srcUrl, data):
   
if not os.path.exists('DOWNLOAD'):
        os.makedirs(
'DOWNLOAD')

    parser = ImageParser()
    parser.feed(data)
    resultSet=
set(x for x in parser.result)

   
for x in sorted(resultSet):
        src = urljoin(srcUrl,x)
#이 함수는 baseURL과 파일명을 합쳐서 완벽한 URL을 리턴하는 함수
        basename = os.path.basename(src)
        targetfile = os.path.join(
'DOWNLOAD',basename)

       
print "Downloading...",src
        urlretrieve(src, targetfile)
#이 함수는

def main():
    host =
"www.google.co.kr"
   
conn = httplib.HTTPConnection(host)
    conn.request(
"GET","")
    resp=conn.getresponse()

    charset = resp.msg.getparam(
'charset')
    data=resp.read().decode(charset)
    conn.close()

   
print "\n Download Image from",host
    url = urlunparse((
'http',host,'','','','')) #이 함수는 urlparser과 반대기능
    downloadImage(url,data)

if __name__ == '__main__':
    main()

C:\Users\사용자폴더\PycharmProjects\untitled\DOWNLOAD 에 저장된다.

 

3. 웹 서버 라이브러리

웹 서버 프로그램을 작성할 때 개발자가 직접 라이브러리를 사용하여 개발하기 보다는 웹 프레임워크를 사용해서 개발하는 경우가 많다.

*프레임워크?
: 개발자가 웹 서버 프로그램을 개발하기 쉽도록 저수준의 기능을 이미 만들어 놓은 프로그램

당장 웹 서버 에플리케이션을 주로 개발할 것이라면 웹 프레임워크를 공부하면 되지만, 차후에라도 웹 서버의 내부 동작을 분석할 때를 대비하여 웹 서버 라이브러리의 기본 개념과 동작 원리를 공부하자..

•간단한 웹 서버 만들기

웹 서버의 역할은 http통신에서 클라이언트의 요청을 받고 이를 처리하여 결과를 돌려주는 것
웹 클라이언트로부터 요청을 받고 “Hello Network Team”이라는 문장을 되돌려주는 서버를 만들어보자.
웹 서버를 만드는 기본적인 방법은 다음과 같다.


from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler

class Myhandler(BaseHTTPRequestHandler):
   
def do_GET(self):
       
self.wfile.write("Hello Network Team")

if __name__ == '__main__':
    server=HTTPServer((
'',8888),Myhandler)
   
print "started web Server on port 8888"
   
print "Press cancle to quit web Server"
   
server.serve_forever()


# python에선 웹 서버를 만드는데 필요한 라이브러리를 3개의 모듈로 나누어서 정의하고 있다.

모듈명

모듈에서 정의하고 있는 내용

처리기능

BaseHTTPServer

기반 서버 클래스용으로, HTTPServer 정의

핸들러 클래스용으로, BaseHTTPRequestHandler 정의

테스트용 웹 서버를 실행하는 함수인 test() 정의

기반 클래스로,

HTTP 프로토콜 처리

SimpleHTTPServer

기반 서버 클래스 HTTPServer를 임포트하여 사용

핸들러 클래스용으로 SimpleHTTPRequestHandler 정의

테스트용 웹 서버를 실행하는 함수인 test() 정의

GETHEAD 메소드

처리가능

CGIHTTPServer

기반 서버 클래스 HTTPServer를 임포트하여 사용

핸들러 클래스용으로 CGIHTTPRequestHandler 정의

테스트용 웹 서버를 실행하는 함수인 test() 정의

POSTCGI 처리가능

 

BaseHTTPServer 모듈

앞에서 만든 웹 서버를 실행한 상태에서 웹 브라우저를 켜고 주소창에 http://127.0.0.1:8888/를 적어주면 다음과 같은 메시지가 출력된다.

SimpleHTTPServer 모듈

BaseHTTPServer 모듈을 사용하여 Myhandler라는 핸들러를 코딩했지만, SimpleHTTPServer 모듈에는 간단한 핸들러가 미리 구현되어 있어서 필요할 때 즉시 웹 서버를 실행할 수 있다.

, 별도의 코딩이 없어도 SimpleHTTPServer가 동작한다는 말씀!!

*명령 프롬프트 창을 열어서 다음과 같이 입력하여 웹 서버를 실행해보자.


CGIHTTPServer 모듈

CGI는 웹 서버를 운영하는 사람이 사용자들로부터 특정 정보를 얻어 자신의 프로그램에 사용하려고 할 때 필요한 인터페이스이다. SimpleHTTPServer 모듈과 마찬가지로 간단한 핸들러가 미리 구현되어 있어서 필요할 때 즉시 웹 서버를 실행할 수 있다. 실행방법 또한 같다.(python –m CGIHTTPServer 8888)

 

•앞의 HTTPServer 모듈 간의 관계

BaseHTTPServer모듈이 기본이 되고 이를 확장한 모듈이 SimpleHTTPServer모듈이며, CGIHTTPServer 모듈은 SimpleHTTPServer을 확장하여 작성된 것!

[HTTPServer 모듈의 클래스 간 상속도]

 

핸들러 클래스는 각 모듈마다 정의되어 있으며, 각 핸들러 클래스는 상위 모듈의 핸들러 클래스를 상속받아 정의하고 있다.

참고로, HTTP 프로토콜은 TCP 프로토콜 기반으로 동작하므로 TCP 프로토콜을 처리하는 SocketServer모듈의 클래스도 같이 표시해두었다.

 

쉽게 말하자면, 앞서 사용하였던 각 모듈의 test()함수는 각 상위 모듈로 호출하여 체인처럼 엮여 있어서 가능한 일인 것!


※Reference--------------------------------------------------
파이썬 웹프로그래밍 (Django(장고)로 배우는 쉽고 빠른 웹개발)  김석훈 저  한빛미디어


댓글