티스토리 뷰

반응형

urllib

파이썬에서는 웹과 관련된 데이터를 쉽게 다룰 수 있도록 urllib모듈을 제공한다. python2 버전에서의 urlparse가 python3에서는 urllib.parse로 변경됐다.

 

docs.python.org/3/library/urllib.html#module-urllib

 

urllib — URL handling modules — Python 3.9.1 documentation

 

docs.python.org

 

위의 내용이 공식문서이다. 아래의 내용은 자주 사용하는 내용위주로 정리해 보겠다.

 

 

공식문서에서 볼 수 있듯, urllib은 모듈을 핸들링하는 URL이라고 적혀있다. urllib의 모듈에는 urllib.request, urllib.error, urllib.parse, urllib.robotparser가 있다는 것을 알 수있다.

 

 

urllib.request

urllib.request 모듈은 다이제스트 인증, 리디렉션, 쿠키등과 같은 URL이나 HTTP를 여는 데 도움이 되는 함수와 클래스를 정의한다. 즉, urlib.request를 사용하면 간단하게 웹 페이지 요청 및 데이터를 가져오는 것이 가능하다. 중요내용 위주로 정리해 보자.

  • digeat authentication이란, 다이제스트 액세스 인증은 웹 서버가 사용자의 웹 브라우저와 사용자 이름 또는 암호와 같은 자격 증명을 협상하는 데 사용할 수있는 합의 된 방법 중 하나이다. 온라인 뱅킹 거래 내역과 같은 민감한 정보를 보내기 전에 사용자의 신원을 확인하는 데 사용할 수 있다.

 

 

 

urllib.request.urlopen

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)¶

 

urlopen은 stiring이나 Request 객체인 URL을 열어준다. 수많은 옵션들이 있지만, 사실 대부분 url을 많이 쓴다. 예시를 통해 이해해보자. url부분만 넣어서 보내면 html을 돌려준다. read를 통해 읽을 수 있다.

 

우선은 url을 넣어서 결과 값을 확인해 보자.

 

from urllib.request import urlopen    
response = urlopen('http://www.google.co.kr')  
print(response)

'''
<http.client.HTTPResponse at 0x25e63f57c18>
'''

 

리턴값으로 호출하여 얻은 데이터를 보면 데이터에 대한 객체를 반환하는 것을 알 수 있다.

 

 

실제로 결과 값을 보고 싶다면 read 함수를 실행해 주면 된다. 이때 아래와 같이 decode를 하지 않으면 인코딩된 페이지의 결과가 보이지 않기 때문에 읽기가 어렵다.

 

from urllib.request import urlopen    
response = urlopen('http://www.naver.com')  
response.read().decode("utf-8")

'''
'\n<!doctype html>                <html lang="ko" data-dark="false"> <head> 
<meta charset="utf-8"> <title>NAVER</title> <meta http-equiv="X-UA-Compatib
le" content="IE=edge"> <meta name="viewport" content="width=1190"> <meta nam
e="apple-mobile-web-app-title" content="NAVER"/> <meta name="robots" content="
index,nofollow"/> <meta name="description" content="네이버 메인에서 다양한 정보
와 유용한 컨텐츠를 만나 보세요"/> <meta property="og:title" content="네이버"> <me
ta property="og:url" content="https://www.naver.com/"> <meta property="og:imag
e" content="https://s.pstatic.net/static/www/mobile/edit/2016/0705/mobile_2128
52414260.png"> <meta property="og:description" content="네이버 메인에서 다양한 정
보와 유용한 컨텐츠를 만나 보세요"/> <meta name="twitter:card" content="summary"> <
meta name="twitter:title" content=""> <meta name="twitter:url" content="https:/
/www.naver.com/"> <meta name="twitter:image" content="https://s.pstatic.net/s
tatic/www/mobile/edit/2016/....
'''

 

 

 

상태값(HTTP Status)을 가져오기 위해서는 아래와 같이 반환된 객체의 status 변수를 이용하면 된다.

 

>>> from urllib.request import urlopen    
>>> response = urlopen('http://www.google.co.kr')  
>>> response.status

200

 

urllib.request.urlopen은 URL을 여는 함수인데 URL 열기에 성공하면 response.status의 값이 200이 나옵니다. 이 200은 HTTP 상태 코드이며 웹 서버가 요청을 제대로 처리했다는 뜻입니다.

 

 

>>> from urllib.request import Request, urlopen    # urlopen 함수, Request 클래스를 가져옴
>>> req = Request('http://www.google.co.kr')       # Request 클래스를 사용하여 req 생성
>>> response = urlopen(req)                        # urlopen 함수 사용
>>> response.status
200

urlopen 함수에 URL을 바로 넣어도 되고, Request 클래스에 URL을 넣은 뒤에 req를 생성해서 urlopen 함수에 넣어도 됩니다.

 

 

 

urlretrieve

urlretrieve를 활용하여 우리는 url이 가리키는 주소에 접근해서 해당 자원을 로컬 컴퓨터에 저장할 수 있다. 이것을 활용하여 우리는 이미지를 저장하는 것이 가능하다.

 

import urllib.request

url = "--마우스우클릭으로 이미지 주소 복사한 내용--"
savename = "./저장할이미지이름.jpg"

# url이 가리키는 주소에 접근해서 해당 자원을 로컬 컴퓨터에 저장하기
urllib.request.urlretrieve(url, savename)

print("저장완료!!!")

 

추가적으로 urlopen을 활용하여 바운받은 이미지 파일을 메모리에 저장 한 후에 open을 활용하여 파일로 저장해 보자.

 

import urllib.request

url = "--마우스우클릭으로 이미지 주소 복사한 내용--"
savename = "./저장할이미지이름.jpg"

image = urllib.request.urlopen(url).read()

# wb는 Write Binary
with open(savename, mode="wb") as f:
    #메모리의 이미지를 파일로 저장
    f.write(image)
    print(저장완료!!)

 

text가 아닌 형태는 바이너리로 주어지기 때문에 "wb"를 사용한다.

 

 

 

 

urllib.error

from urllib.request import urlopen
from urllib.error import HTTPError
from urllib.error import URLError

try:
    html = urlopen("https://java.com")
except HTTPError as e:
    print("HTTP 에러입니다.")
except URLError as e:
    print("존재하지 않는 사이트입니다.")
else:
    print(html.read())
    
    
'''
java.com의 사이트를 불어온 출력값이 나타난다.
'''

 

만약 없는 URL를 작성했다면 URLError이 발생되고, 사이트의 서버에서 접근을 막았다면 HTTPError가 발생한다. 아래는 java를 jaba라고 고의적으로 없는 url을 적어보았다.

 

from urllib.request import urlopen
from urllib.error import HTTPError
from urllib.error import URLError

try:
    #html = urlopen("https://java.com")
    html = urlopen("https://jaba.com")
except HTTPError as e:
    print("HTTP 에러입니다.")
except URLError as e:
    print("존재하지 않는 사이트입니다.")
else:
    print(html.read())
    
    
'''
#output
존재하지 않는 사이트입니다.
'''

 

즉, 존재하지 않는 사이트라면 URLError가 보일 것이고, 만약 네이버나 구글같은 곳에서 사이트를 막아놨다면 HTTPError가 뜰것이다. 

 

 

 

urllib.parse

간단한 문자열 파싱 시에 보통은 정규표현식을 많이 사용하긴한다. 그러나 단순한 패턴을 읽을 때에는 복잡한 정규표현식보다는 간단한 parse 모듈을 사용하는 것도 가능하다.

 

urllib.parse 모듈로 URL과 파라미터를 다룰 수 있다. URL을 파싱하기 위해서는 urlparse 함수를 이용하면 된다. 우선은 url을 파싱(자동으로 쪼개준다.)해보자.

 

from urllib import parse
url = parse.urlparse("https://예시도메인/articles/2?test=hanpy&key=abcd")
print (url)

'''
ParseResult(scheme='https', netloc='예시도메인', path='/articles/2', params='', query='test=hanpy&key=abcd', fragment='')
'''

print(url.query)

'''
'test=hanpy&key=abcd'
'''

 

 

알아서 나눠주기 때문에 쿼리를 쓰려면 url.query를 사용하면 된다. 추가적으로 parse_qs 함수를 사용하면 리턴 타입이 딕셔너리로 되기 때문에 쿼리 스트링을 더 쉽게 가져올 수 있다. 아래의 예를 보자.

 

from urllib import parse
url = parse.urlparse("https://예시도메인/articles/2?test=hanpy&key=abcd")
print(parse.parse_qs(url.query))

'''
{'test': ['hanpy'], 'key': ['abcd']}
'''

 

결과값을 보면 알 수 있듯이 딕셔너리형태로 리턴된다. 그렇기 때문에 index를 이용해서 필요한 값들을 뽑을면 된다.

 

 

 

 

인코딩 처리도 가능하다. 공백을 +로 처리 할 때는 quote_plus 함수를 사용하고, 공백을 %20으로 처리할 때는 quote 함수를 사용한다.

 

위의 공식문서에서 나오듯 quote는 문자열을 퍼센티지 이스케이프를 사용하는 문자열로 바꿔준다. 예는 아래와 같다.

 

from urllib.parse import quote, quote_plus
print('파이썬은 hanpy')
print(quote('파이썬은 hanpy'))
print(quote_plus('파이썬은 hanpy'))

#output
'''
파이썬은 hanpy
%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9D%80%20hanpy
%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%9D%80+hanpy
'''

 

quote와 quote_plus의 차이는 없어보이지만, 띄어쓰기를 출력해주는 방식이 다르다.

 

 

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함