크롤링이란 무엇일까?
크롤링(crawling) 혹은 스크랩핑(scraping)이란 웹페이지에 있는 데이터들을 프로그래밍적으로 추출하는 것을 뜻한다.
쉽게말해 각기다른 웹 페이지에서 내가 원하는 데이터 또는 필요한 데이터를 프로그맹적으로 추출하여 다시 활용가능한 형태로 만드는 것이다.
*스크래핑 - 각각의 페이지에서 정보를 추출하는 행위
&*크롤러 - 자동으로 정보추출을 반복하는 프로그램
크롤링의 원리를 이해하기 위해서는 웹페이지의 구성을 알고 있으면 좋다.
구조를 잡는 HTML, 디자인을 하는 CSS, 사용자와 동적으로 상호작용하는 Javascript로 이루어져있다.
이전의 <웹 스크랩핑 준비과정>이라는 글에서 잠깐이나 Rest API에 대해 다루어 보았지만 한번 더 다루어보겠다.
위에서 웹 페이지(Web page)에 대해 알아 봤으니 이제 서버(server)와 클라이언트(client)에 대해 알아보자
*서버: 요청에 대해 응답을 해주는 프로그램
*클라이언트: 서비스를 요청하는 프로그램
크게 보면 웹 페이지는 아래와 같은 방식으로 작동한다.
위의 자료를 보면 웹페이지는 클라이언트와 서버사이에 요청과 응답을 통해 작동하고 있다는 것을 알 수 있다.
그래서 요청과 응답등 정보를 주고 받을때 서버와 클라이언트사이에 특정한 규약이있는데 그것이 HTTP이다.
REST API는 HTTP를 사용하여 통신할때 더 체계적인 관리를 위해 통일된 메서드를 만든것이다.
즉 REST API는 HTTP를 사용하는 통신에서 클라이언트가 서버에게 요청을 할때 사용하는 메서드이다.
대표적으로 CRUD 를 통해 대표적인 요청메서드 4가지를 분류할 수 있다.
- Create = POST
- Read = GET
- Update = PUT, PATCH
- Delete = DETELE
[응답 상태코드 구분]
1xx : Informational (단순 정보 제공)
2xx : Successful (성공)
3xx : Redirect (추가 정보 필요)
4xx : Client error
5xx : Server error
위에서 웹 페이지(Web page)의 구성과 서버(server), 클라이언트(client)간의 요청과 응답에 대해 공부해봤다.
다음으로는 HTTP Client 모듈-[python] 에 대해 알아보자.
- urllib
- Python built-in module
- 간편하게 HTTP request를 보낼 수 있음
- 로그인 및 세션을 유지하기가 번거로움
- Requests #https://docs.python-requests.org/en/master/
- 간편하게 HTTP request를 보낼 수 있음
- 세션을 유지하기가 용이함
- 코드가 간결하고 documentation이 잘 되어 있음
- Selenium : 웹브라우저 자동화 tool #https://selenium-python.readthedocs.io/
- javascript/css 지원, 기존 GUI 브라우저 자동화 라이브러리
- 사람이 웹서핑 하는 것과 동일한 환경, 대신에 리소스를 많이 사용함
- 웹브라우저에서 HTML에 명시된 이미지/CSS/JavaScript를 모두 자동 다운로드/적용
다양한 http client module을 알아보았다.
그중에서 requests module 사용법을 자세히 알아보자.
[기본 사용 방식]
import requests
requests.get(...) #get요청 (주로 html조회요청)
requests.post(...) #post요청 (주로 추가/수정/삭제요청)
# get과 post의 차이 :
# get은 데이터를 가져오는데 사용되고,
# post는 서버의 데이터를 수정하는데 사용된다.
requests.put(...) #put요청
requests.delete(...) #delete요청
r = requests.get(url 주소) #url주소에 데이터 요청
r.content # 응답 데이터(binary형식 내용,이미지파일 등)
r.text # 응답 데이터(텍스트형식 내용, 텍스트 파일에 씀)
r.json # 응답 데이터 JSON형태
r.url # 해당 url 반환
r.status_code # 응답 상태코드 (200 이면 성공)
r.headers # 응답 헤더의 {K:V} 형식의 딕셔너리 자료반환
r.encoding = 'utf-8' # 응답 객체에 인코딩 지정
[사용 예시]
1. 요청시 headers에 User-Agent 정보를 크롬으로 지정하여 요청
mport requests
# 요청시 헤더정보를 크롬으로 지정
request_headers = {
'User-Agent' : ('Mozilla/5.0 (Windows NT 10.0;Win64; x64)\
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98\
Safari/537.36'), }
url = "https://search.naver.com/search.naver"
response = requests.get(url,headers = request_headers)
print(response)
#해당 url 요청할 때 headers를 임의로 설정하여 요청한 케이스
2. 요청시 headers에 Referer 정보를 바꾸어 웹에서 접속한 것으로 요청.
월요웹툰 페이지에서 접속한 것으로 요청하여, 웹툰 이미지 파일 가져오기
import os
import requests
image_url = 'https://image-comic.pstatic.net/webtoon/626907/237\
/20190115192015_d9f2b6e9d878a372dfa6f07ebfc5f14a_IMAG01_1.jpg'
# Referer을 지정하여 수요웹툰 복학왕 페이지를 통해서 요청
headers = {'Referer': 'https://comic.naver.com/webtoon/list.nhn?\
titleId=626907&weekday=wed'}
response = requests.get(image_url, headers = headers)
print(response) # 접속 확인 (200 = 성공)
image_data = response.content # binary형식
imgfile = os.path.basename(image_url) # url을 이름으로 하는 비어있는 데이터생성
#파일에 이미지 데이터를 넣기
with open(imgfile, 'wb') as f:
f.write(image_data)
3. 요청시 params지정을 활용한 뉴스기사 웹 크롤링
import requests
# 데이터를 요청하고자 하는 url = https://news.naver.com/main/read.nhn?\
# mode=LS2D&mid=shm&sid1=101&sid2=259&oid=009&aid=0004299807
# params를 지정하여 요청하는 것은 url뒤에 자동으로 ?와 &연산자로 묶어주는역할
url = "https://news.naver.com/main/read.nhn"
get_params = {
'mode': 'LS2D',
'mid': 'shm',
'sid1': '101',
'sid2': '259',
'oid': '029',
'aid': '0002506893'
}
r = requests.get(url,params=get_params)
print(r.text)
#해당 뉴스기사 데이터 가져오는 것 확인
댓글