본문 바로가기
[python]데이터 분석/[python]웹 스크랩핑(scraping)

[python]웹 크롤링 이해하기

by 코드몽규 2022. 1. 31.
반응형
크롤링이란 무엇일까?

크롤링(crawling) 혹은 스크랩핑(scraping)이란 웹페이지에 있는 데이터들을 프로그래밍적으로 추출하는 것을 뜻한다.

쉽게말해 각기다른 웹 페이지에서 내가 원하는 데이터 또는 필요한 데이터를 프로그맹적으로 추출하여 다시 활용가능한 형태로 만드는 것이다.
*스크래핑 - 각각의 페이지에서 정보를 추출하는 행위
&*크롤러 - 자동으로 정보추출을 반복하는 프로그램

크롤링의 원리를 이해하기 위해서는 웹페이지의 구성을 알고 있으면 좋다.

웹페이지의 구성/ 이미지 출처: https://twoearth.tistory.com/19

 

구조를 잡는 HTML, 디자인을 하는 CSS, 사용자와 동적으로 상호작용하는 Javascript로 이루어져있다.


 

이전의 <웹 스크랩핑 준비과정>이라는 글에서 잠깐이나 Rest API에 대해 다루어 보았지만 한번 더 다루어보겠다.

 

위에서 웹 페이지(Web page)에 대해 알아 봤으니 이제 서버(server)와 클라이언트(client)에 대해 알아보자 

*서버: 요청에 대해 응답을 해주는 프로그램

*클라이언트: 서비스를 요청하는 프로그램

 

크게 보면 웹 페이지는 아래와 같은 방식으로 작동한다.

web의 이해 / 웹 페이지 해석 순서

위의 자료를 보면 웹페이지는 클라이언트서버사이에 요청과 응답을 통해 작동하고 있다는 것을 알 수 있다.

 

그래서 요청과 응답등 정보를 주고 받을때 서버와 클라이언트사이에 특정한 규약이있는데 그것이 HTTP이다.

 

REST API는 HTTP를 사용하여 통신할때 더 체계적인 관리를 위해 통일된 메서드를 만든것이다.

 

즉 REST API는 HTTP를 사용하는 통신에서 클라이언트가 서버에게 요청을 할때 사용하는 메서드이다.

 

대표적으로 CRUD 를 통해 대표적인 요청메서드 4가지를 분류할 수 있다.

 

REST API CRUD

  • 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를 모두 자동 다운로드/적용
 

Selenium with Python — Selenium Python Bindings 2 documentation

Note This is not an official documentation. If you would like to contribute to this documentation, you can fork this project in GitHub and send pull requests. You can also send your feedback to my email: baiju.m.mail AT gmail DOT com. So far 50+ community

selenium-python.readthedocs.io


다양한 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) 
#해당 뉴스기사 데이터 가져오는 것 확인
반응형

댓글