안녕하세요 펭귄 교수입니다.
이번에는 웹과 파이썬 강의 시간입니다.
웹 파트는 총 3가지 라이브러리로 나누어 설명하고자 합니다.
HTTP 프로토콜을 이용하여 데이터를 가져오는 requests,
웹 크롤링을 위한 Beautiful Soup,
동적 웹 크롤링, 웹 이벤트를 위한 Selenium 입니다.
웹 서버에 대한 프레임 워크인 Django나 Flask는 별도로 진행하겠습니다.
requests 라이브러리를 사용하기 전 HTTP 에 대한 설명을 잠깐 드리겠습니다.
1. HTTP
HyperText Transfer Protocol
우리가 인터넷 주소창에 입력하는 그 http 입니다. https 는 뒤에 Secure가 붙은 것으로 보안을 추가로 한 시스템이죠.
이걸 자세하게 설명하려면 아예 컴퓨터 네트워크로 들어가야 하니 다음에 설명드리겠습니다.
HTTP는 서버-클라이언트가 통신을 위해 사용되는 프로토콜 입니다.
이 프로토콜 종류에는 TCP와 UDP가 있고, HTTP는 주로 TCP 통신을 사용합니다.
간단하게 설명드리면 TCP는 통신하는 과정에서 누락된 데이터가 없는 지, 잘못 전송된 데이터가 없는 지를 계산합니다.
반대로 UDP는 모든 데이터가 잘 갔다라는 가정하에 계산되죠.
그렇기 때문에 TCP는 속도가 UDP보다는 느리지만 안정성이 있고, UDP는 안정성이 다소 떨어지지만 속도가 빠른다는 장점이 있습니다.
이 HTTP를 설명하는 제일 큰 이유는 HTTP의 메소드에 있습니다.
1-1. HTTP 메소드
HTTP 메소드란, 통신에 있어서 어떤 통신인지 먼저 보내는 형식입니다.
이 형식의 종류는 다음과 같습니다.
- POST : 주로 데이터가 새로 추가될 때 사용됩니다.
- GET : 서버로부터 데이터를 받을 때 사용됩니다.
- PUT : 데이터를 업데이트할 때 사용됩니다.
- DELETE : 데이터를 삭제할 때 사용됩니다.
아마 웹 프로그래밍을 하셨던 분들은 많이 보셨을 메소드입니다.
HTML의 <FORM 태그>에서 <METHOD="POST"> 라고 되어 있던 이 POST가 위의 메소드를 의미합니다.
이 requests 라이브러리는 해당 방식을 이용하기 때문에 먼저 소개드립니다.
1-2. HTTP 응답 코드
또한 추가적으로 알아둬야 할 것은 HTTP 응답 코드입니다. Status Code라고 불리기도 합니다.
서버로부터 받은 응답 코드가 무엇이냐에 따라 어떤 에러인지, 데이터가 잘 전송되었는 지를 알 수 있습니다.
응답 코드는 총 5 가지의 종류가 있고, 이를 먼저 소개하고, 자세하게 설명드리겠습니다.
- 1XX : Information (정보 교환)
- 2XX : Success (데이터 전송 성공, 수락)
- 3XX : Redirection (자료 위치 변경)
- 4XX : Client Error (클라이언트 측 오류)
- 5XX : Server Error (서버 측 오류)
뒤에 XX는 다른 숫자들을 의미합니다. 만약 웹 크롤링이나 웹 클라이언트 작업하다가 처음 보는 응답 코드를 받았을 때, 위와 같은 사항을 보고 크게 어떤 문제 겠구나를 알 수 있습니다.
그러면 대표적인 응답 코드 몇개를 소개드리도록 하겠습니다.
- 200 : 오류 없이 성공
- 202 : 서버가 클라이언트 요청 수락
- 400 : 문법 상 오류로 요청 사항 이해 불가
- 401 : 권한 없음 (.X 로 여러 가지 상황이 있음)
- 403 : 접근 금지 (.X 로 여러 가지 상황 있음)
- 404 : 문서를 찾을 수 없음 (대체로 주소 잘못 입력)
- 405 : 메소드 허락 안됨
- 502 : 게이트웨이 상태 나쁨 (서버 터졌을 때 보통 나오는 응답 코드)
2. Requests 라이브러리
그러면 이제 본격적으로 파이썬을 통해 웹 접속을 해보도록 하겠습니다.
먼저 requests 라이브러리는 기본 내장 라이브러리가 아니므로, 설치를 해주어야 합니다.
2-1. 설치
pip install requests
그 후 기본 뼈대가 되는 코드를 보여드리겠습니다.
2-2. 코드
import requests
with requests.get('http://www.google.com') as response:
if response.status_code != 200:
print(response.status_code)
exit()
print(response.text)
1. 라이브러리 Import
2. with 문을 사용하여 requests.get() 메서드 실행
3. response라는 변수에 가져온 데이터 삽입
4. 응답 코드가 200이 아닐 경우 어떤 응답 코드인 지 출력 후 프로그램 종료
5. 응답 코드가 200일 경우 받아온 텍스트 값 출력
실행 결과 입니다.
제대로 get해서 구글의 HTML 소스 코드를 가져왔습니다.
이때 get은 위 HTTP의 메소드 GET과 동일한 개념입니다.
2-3. Header (POST Method)
import requests
import json
data = {'key': 'value'}
headers = {'Content-type': 'application/json'}
with requests.post('http://httpbin.org/post', data=json.dumps(data), headers=headers) as response:
print(response.text)
데이터를 넣어 서버에 POST 메서드 방식으로 데이터 전송 또한 가능합니다.
2-4. response.json()
response.json() 을 이용하면 Json (Dictionary) 형태로 값을 받아 올 수도 있습니다.
import requests
import json
data = {'key': 'value'}
headers = {'Content-type': 'application/json'}
with requests.post('http://httpbin.org/post', data=json.dumps(data), headers=headers) as response:
jsonData = response.json()
print(jsonData['headers'])
2-5. Cookies
웹 페이지의 쿠키 값도 가져오거나 전송할 수 있습니다.
import requests
cookie = {'cookie_name': 'cookie_value'}
with requests.post('http://sample.com', cookies=cookie) as response: # 쿠키 보내기
cookie_name = response.cookies['cookie_name'] # 쿠키 가져오기
2-6. Byte 단위 데이터 출력 (Binary 형태 데이터)
Binary 형태의 데이터는 response.content 형식으로 가져올 수 있습니다.
서버로부터 이미지, 영상, 음원 등을 받을 때 유용하게 사용될 거 같습니다.
import requests
with requests.post('http://sample.com') as response:
if response.status_code != 200:
print(response.status_code)
exit()
print(response.content)
2-7. try 문을 사용한 에러 잡기
raise_for_status() 라는 메서드를 사용해 에러를 잡을 수도 있습니다.
import requests
from requests.exceptions import RequestException
with requests.get('http://sample.com') as response:
try:
response.raise_for_status()
print(response.text)
except RequestException as error:
print(error)
3. 관련한 에러 해결
requests 라이브러리를 사용하면 종종 나는 에러에 관해 해결 방법도 같이 보여드리겠습니다.
3-1. 한글 깨짐 문제
해당 문제는 인코딩 방식의 문제가 있는 경우가 많습니다.
특히 한글이 유니코드로 변환되는 경우는 모두 인코딩 방식 문제라 봐도 무방합니다.
MySQL에서 비슷한 문제를 겪어본 적도 있었죠
requests에서 발생하는 문제는 repsonse.encoding = 'utf-8' 로 해결할 수 있습니다.
import requests
from requests.exceptions import RequestException
with requests.get('http://google.com') as response:
try:
response.raise_for_status()
response.encoding = 'utf-8'
print(response.text)
except RequestException as error:
print(error)
3-2. 신뢰하지 않은 SSL 인증서 설치된 웹 페이지 접근
HTTPS로 되어 있지 않거나, Secure을 위한 SSL 인증서가 만료된 경우, 제대로 된 인증서를 설치하지 않은 서버를 GET할 경우 제대로 출력되지 않습니다.
이러한 문제는 verify=False를 이용해 SSL 인증 절차를 생략하여 해결할 수 있습니다.
import requests
from requests.exceptions import RequestException
with requests.get('http://google.com', verify=False) as response: # verify=False 옵션 추가
try:
response.raise_for_status()
print(response.text)
except RequestException as error:
print(error)
마무리
이렇게 파이썬 requests 라이브러리와 HTTP에 대한 간단한 개념까지 알아보았습니다.
API를 통해 데이터를 가져와 사용하는 경우 이 requests 라이브러리는 상당히 유용한 라이브러리 입니다.
하지만 웹 크롤링을 할 때는 다소 힘들 수 있습니다.
HTML 코드는 방대할 뿐만 아니라 태그들이 있어서 이를 단순히 텍스트로 파싱하는 것에는 한계가 있기 때문입니다.
그래서 다음 시간에는 이를 도와줄 다른 라이브러리 Beautiful Soup 에 관하여 이야기해보도록 하겠습니다.
감사합니다.
다른 글 더보기
'프로그래밍 > Python' 카테고리의 다른 글
[파이썬 코딩 강의] 웹과 파이썬 (Selenium 편) (1) | 2024.10.07 |
---|---|
[파이썬 코딩 강의] 웹과 파이썬 (Beautiful Soup 편) (1) | 2024.10.03 |
[파이썬 코딩 강의] 객체 지향 언어 (1) | 2024.09.26 |
[파이썬 코딩 강의] 클래스와 메서드 (0) | 2024.09.21 |
[파이썬 코딩 강의] 함수, 모듈화 (0) | 2021.03.09 |