파이썬

파이썬 urlopen()함수 예제 - Request 클래스로 요청 헤더 지정

mcdn 2020. 9. 10. 12:55
반응형

urllib.request 모듈에 있는 urlopen()함수는 주어진 url에서 데이터를 가져오는 기본 기능을 제공한다. 

 

가장 간단한 웹 클라이언트 프로그램 만들기 

from urllib.request import urlopen
f=urlopen("http://www.example.com")
print(f.read(500).decode('utf-8'))

위는 가장 간단한 GET방식의 요청 클라이언트 프로그램이다. 

GET방식은 웹브라우저가 데이터를 끌어오는 것이랑 같은 원리로 가져온다. 

 

다음은 POST방식 

from urllib.request import urlopen
data = 'language=python&framework=django'
f = urlopen("http://127.0.0.1:8000", bytes(data, encoding='utf-8')
print(f.read(500).decode('utf-8'))

POST방식은 지정해준 data인자가 url허용 문자열로 인코딩된 상태여야 하고 유니코드 타입이 아니라 바이트 스트링 타입이어야 한다. 

 

 

다음은 Request 클래스로 요청 헤더를 지정하는 예시다. pg 53 

Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 21:26:53) [MSC v.1916 32 bit (Intel)] on win32
from urllib.request import urlopen, Request
from urllib.parse import urlencode
url = 'http://127.0.0.1:8000'
data = {}
data = {
    'name' : '김석훈',
    'email' : 'shi@naver.com',
    'url' : 'http://www.naver.com',
    }
encData = urlencode(data)
postData = bytes(encData, encoding = 'utf-8')
req = Request(url, data=postData)
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
f = urlopen(req)
print(f.info())
Date: Thu, 10 Sep 2020 02:56:54 GMT
Server: WSGIServer/0.2 CPython/3.7.3
Content-Type: text/html
X-Frame-Options: DENY
Content-Length: 16351
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
print(f.read(500).decode('utf-8'))
e-height: 1.15;
            -ms-text-size-adjust: 100%;
            -webkit-text-size-adjust: 100%;
            box-sizing: border-box;
          }
          footer, header, main {
            display: block;
          }
          a {
            background-color: transparent;
            -webkit-text-decoration-skip: objects;
            color: #19865C;
            text-decoration: none;
          }
          img {
            border-style: none;
          }
          header {
            borde

만일 요청을 보낼 때 요청 헤더를 지정해서 보내고 싶은 경우에는 URL을 지정하는 방식으로 변경하면 됩니다. 

url인자에 문자열 대신에 Request 객체를 지정합니다. 

req = Request(url, data=PostData)

즉 Request 객체를 생성하고 add_header() 함수로 헤더를 추가하여 웹서버로 요청을 보내면 됩니다. 

req.add_header('Content-Type', 'application/x-www-form-urlencoded')

 

POST요청을 보내기 위해서는, urlopen()함수와 마찬가지로 Request 객체를 생성할 때 data인자를 지정해줍니다. 

 

ch2-test-server를 실행하고 실습해야 한다. 

python manage.py runserver. 

만약 서버를 키지 않고 하면 

from urllib.request import urlopen, Request
from urllib.parse import urlencode
url = 'http://127.0.0.1:8000'
data = {
    'name':'kim',
    'email' : 'si@naver.com',
    'url':'http://www.naver.com',
    }
encData = urlencode(data)
postData=bytes(encData,encoding='utf-8')
req = Request(url,data=PostData)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'PostData' is not defined
req = Request(url,data=postData)
req.add_header('Content-Type','application/x-www-form-urlencoded')
f=urlopen(req)
Traceback (most recent call last):
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py", line 1317, in do_open
    encode_chunked=req.has_header('Transfer-encoding'))
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\http\client.py", line 1229, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\http\client.py", line 1275, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\http\client.py", line 1224, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\http\client.py", line 1016, in _send_output
    self.send(msg)
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\http\client.py", line 956, in send
    self.connect()
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\http\client.py", line 928, in connect
    (self.host,self.port), self.timeout, self.source_address)
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\socket.py", line 727, in create_connection
    raise err
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\socket.py", line 716, in create_connection
    sock.connect(sa)
ConnectionRefusedError: [WinError 10061] 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py", line 525, in open
    response = self._open(req, data)
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py", line 543, in _open
    '_open', req)
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py", line 503, in _call_chain
    result = func(*args)
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py", line 1345, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "C:\Users\user\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py", line 1319, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [WinError 10061] 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다>

f = urlopen(req)

즉 urlopen()함수를 쓸때 에러가 난다. 

'대상 컴퓨터에서 연결을 거부했으므로...'

 

auth_handler.add_password(realm='ksh', user='shkim', passwd=shkimadmin, uri='http://127.0.0.1:8000/auth/')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'shkimadmin' is not defined

 자기껄로 해야한다. 

 

 

그외에도 쿠키를 요청하거나 프록시 처리를 할 수도 있다. 

반응형