230418 화요일
학습 주제 - Web Scraping 기초
1-1. 인터넷 사용자 간의 약속, HTTP
사실 강의자료가 가장 정리가 잘 되어있는 문서이지만 그래도 한 번 정리를 해보겠다,,,ㅎㅎ
컴퓨터가 탄생했다.
컴퓨터와 컴퓨터를 연결하면 어떻게 될까? => Network!
Network + Network + ... => 근거리 지역 네트워크(Local Area Network, LAN) => 범 지구적으로 연결된 Inter Network 인터넷(Internet)!!!!
인터넷에서 정보를 교환할 수 있는 환경을 만들어볼까? => WWW(World Wide Web)
웹 상에서는 어떻게 정보를 주고받지? => 클라이언트(Client, 정보를 요청)와 서버(Server, 정보를 제공) 둘 다 컴퓨터임.
HTTP(Hypertext Transfer Protocol)이란 웹 상에서 클라이언트와 서버가 정보를 주고받기 위한 약속이다.
클라이언트가 서버로 정보를 요청하는 것을 HTTP 요청(Request)이라 한다.
반대로 서버가 클라이언트에게 응답하는 것은 HTTP 응답(Response)라 한다.
이 정보 요청/응답에 대한 정보(ex. 보내는 사람, 받는 사람 ...)를 담는 Head와 내용물이 들어있는 Body가 있다.
Head - Method, Path, content-type, date
Body - 우리가 보는 페이지의 내용
1-2. 웹 페이지와 HTML
웹 페이지의 모음이 웹 사이트
웹 브라우저는 HTML 요청을 보내고, HTTP 응답에 담긴 HTML 문서를 우리가 보기 쉬운 형태로 화면을 그려주는 역할을 담당한다.
웹 페이지는 HTML(HyperText Markup Language)이라는 형식으로 되어있음.
웹 브라우저는 우리가 Request를 보내고 Response 받은 HTML 코드를 렌더링 해준다.
이 웹 브라우저의 역할을 코드로 대신해 보자!
1-3. 나의 첫 HTTP 통신 코드
python의 requests
라이브러리를 이용해서 HTTP 통신을 진행해 보았다.
먼저 pip install을 통해 requests
라이브러리를 설치한다.
* 여기서 pip이란 python관련 패키지와 모듈들을 설치하는 것을 관리하는 패키지 매니저(Package Management)이다.
node의 npm, yarn / 리눅스의 apt와 같은 패키지 매니저이다.
# %를 이용해서 노트북(.ipynb) 환경에서 터미널 코드를 실행할 수 있다!
%pip install requests
정보를 달라고 요청하기, GET
# requests 라이브러리를 불러온 후, NAVER의 홈 페이지를 요청한 후 응답 받아보기
import requests
res = requests.get("https://www.naver.com")
res # HTTP응답이 담겨있음.
# Header를 확인해봅시다 : .headers
res.headers
# Body를 텍스트 형태로 확인해봅시다 : .text
res.text[:1000]
정보 갱신하는 것을 요청하기, POST
단순히 정보를 가져오는 것뿐만이 아니라 우리의 정보를 제공해 주면서 서버한테 무언가 요청을 진행할 때도 있다.
대표적인 예시로 로그인하는 경우를 생각해 볼 수 있다.
POST method를 사용하기 위해 https://webhook.site 사이트를 이용해 보았다.
# payload와 함께 POST를 보내봅시다 : requests.post()
payload = {"name": "Hello", "age": 13}
res = requests.post("https://webhook.site/82300e41-78a8-452e-9ed9-db385fe34c2c", payload)
# 상태 코드(status code)를 확인해봅시다 : .status_code
res.status_code
1-4. 윤리적으로 웹 스크래핑, 크롤링 진행하기
웹 스크래핑(Web Scraping)이란?
웹 페이지들로부터 우리가 원하는 정보를 추출하는 것
=
특정한 목적으로 특정 웹 페이지에서 데이터를 추출하는 것 - 데이터 추출
e.g. 날씨 데이터 가져오기, 주식 데이터 가져오기, ...
vs
웹 크롤링(Web Crawling)이란?
크롤러(Crawler)를 이용해서 웹 페이지의 정보를 인덱싱하는 것
=
URL을 타고 다니며 반복적으로 데이터를 가져오는 과정 - 데이터 색인
e.g. 검색 엔진의 웹 크롤러
올바르게 HTTP 요청하기 위해 고려해야 할 것들
웹 스크래핑/크롤링을 통해 어떤 목적을 달성하고자 하는가?
나의 웹 스크래핑/크롤링이 서버에 영향을 미치지는 않는가?
로봇 배제 프로토콜(REP, Robot Exclusion Protocol, 1994)
robots.txt
는 웹 사이트 및 웹 페이지를 수집하는 로봇들의 무단 접근을 방지하기 위해 만들어진 로봇 배제 표준(robots exclusive standards)이자 국제 권고안이다.
웹 크롤러들은 이 규칙을 지키면서 크롤링을 진행한다!
일부 스팸봇이나 악성 목적을 지닌 가짜 클라이언트 로봇은 웹 사이트에 진짜 클라이언트처럼 접근한다.
그리고 문단으로 웹 사이트 정보를 긁어가거나, 웹 서버에 부하를 준다.
이런 로봇들의 무분별한 접근을 통제하기 위해 마련된 것이 robots.txt
이다.
우리는 가끔 웹 서버에 요청을 보내도 거부당하는 일이 있는데, 서버는 우리를 이런 무단 봇으로 짐작하고 접근을 막는 것이다.
그럼 우리는 브라우저에게 스팸 봇이 아니라 사람이라는 것을 알려주면 된다.
이때 브라우저에 전달하는 것이 사용자 에이전트(User Agent) 정보이다.
나의 User Agent정보는 https://www.whatismybrowser.com/detect/what-is-my-user-agent/ 이 사이트에서 확인해 볼 수 있다!
사용자 에이전트는 요청을 보내는 것의 주체를 나타내는 프로그램이다.
브라우저, 웹 페이지를 수집하는 봇, 다운로드 관리자, 웹에 접근하는 다른 앱 모두 사용자 에이전트이다.
웹 서버에 요청할 때 사용자 에이전트 HTTP 헤더(user agent HTTP header)에 나의 브라우저 정보를 전달하면 웹 서버가 나를 진짜 사용자로 인식할 수 있게 된다.
사용자 에이전트 헤더를 설정하는 방법을 코드로 살펴보자!
그 전에, 웹 스크래핑을 할 때 원칙은 다음과 같다.
1. 요청하고자 하는 서버에 과도한 부하를 주지 않는다.
2. 가져온 정보를 사용할 때 저작권과 데이터베이스권에 위배되지 않는지 주의한다.
robots.txt 가져오기
웹 페이지의 메인 주소에 '/robots.txt'를 입력하면 확인할 수 있다!
네이버의 경우에는 아래와 같다.
# requests 모듈을 불러온 후, 다음 웹사이트에 대한 robots.txt 정책을 확인해봅시다.
# https://www.naver.com
import requests
res = requests.get("https://www.naver.com/robots.txt")
print(res.text)
- 'User-agent' : 규칙이 적용되는 대상 사용자 에이전트
- 'Disallow' : 크롤링을 금지할 웹 페이지
- 'Allow' : 크롤링을 허용할 웹 페이지
자세한 규약은 robots.txt [공식 홈페이지]("www.robotstxt.org")를 참조하면 된다.
# 여러분이 자주 사용하는 사이트의 robots를 동일한 방법으로 확인해보세요.
res = requests.get("https://sikhyekim.tistory.com/robots.txt")
print(res.text)
위 코드로 알아본 이 블로그의 robots는 아래와 같다 ㅎㅎ
2-1. 웹 브라우저가 HTML을 다루는 방법
DOM(Document Object Model, 문서 객체 모델)
브라우저의 렌더링 엔진은 웹 문서를 로드한 후 파싱을 진행한다. 이때 생성된 것을 DOM이라 한다.
DOM Tree를 순회해서 특정 원소를 찾거나 추가, 변경한다.
브라우저는 왜 HTML을 DOM으로 바꿀까?
원하는 요소를 쉽게 찾을 수 있고 동적으로 변경(feat. javascript)해 줄 수 있기 때문이다.
파이썬으로 HTML을 분석하는 HTML Parser가 필요한데 이는 다음 시간에 알아보장~~
'[프로그래머스] 데이터엔지니어링 데브코스 1기 > TIL (Today I Learned)' 카테고리의 다른 글
TIL_day12 (2) | 2023.04.25 |
---|---|
TIL_day11 (0) | 2023.04.24 |
TIL_day4 (0) | 2023.04.13 |
TIL_day2 (0) | 2023.04.11 |
TIL_day1 (0) | 2023.04.10 |