2019.04.25 동적크롤링(Ajax, JSON)
# 질문에 답하기
- 동적크롤링
- Ajax
- JSON
동적크롤링의 큰 그림
- 자바스크립트로 동작되는 애들은 지속적으로 데이터를 가지고 와서 업데이트 한다.
- 따라서 현재 보이는 데이터를 기준으로 하면 안되고 그 원본 데이터의 주소를 찾아야 한다.
- 먼저 해당 데이터를 불러오는 url을 찾는 것이 중요한데 그것은 network에서 확인할 수 있다.
- XHR을 선택하면 아이젝스로만 활동하는 것을 확인할 수 있고, 거기서 해당 내용을 불러오는 url을 구성한다.
- 그리고 그 url을 통해서 크롤링을 진행해야 하며 동적데이터이기 때문에 이럴 때 이용해야 하는 것은 json이다.
Introduction
- 브라우저(웹클라이언트)에서 웹페이지를 요청하거나 링크를 클릭하면 화면전환이 발생하는데 이것은 브라우저와 서버와의 통신에 의한 것이다.
- 서버는 요청받은 페이지(HTML)를 반환하는데 이때 HTML 뿐만 아니라 CSS 및 javascript파일들도 함께 반환한다.
- 웹페이지가 반환되면 브라우저(웹클라이언트)는 page를 reload하여 화면을 보여준다.
- 서버는 요청받은 페이지가 무엇이냐에 따라 정적인 파일들만 반환할 수도 있고, javascript가 섞인 동적인 파일들을 반환할 수도 있다.
Ajax(Asynchronous javascript and XML)
- Ajax는 자바스크립트를 이용하여 비동기적으로 서버와 브라우저가 데이터를 교환하는 통신 방식이다.
- 서버에서 한번 페이지를 반환했을 때 거기에는 HTML와 같은 정적인 파일들 뿐만 아니라 javascript와 같이 동적인 파일들도 함께 반환한다.
- 만약 페이지에서 일부만 지속적으로 갱신해야 한다면 굳이 모든 파일을 다시 반환할 필요가 없다.
- 따라서 브라우저(웹클라이언트)는 Ajax request를 통해 동적인 부분을 요청하고 서버는 json을 통해 reload하는데 필요한 정보들을 반환 해준다.
[출처 : jQuery Ajax & JSON PoiemaWeb](https://poiemaweb.com/jquery-ajax-json)
Ajax의 요청과 처리
- 웹브라우저는 XMLHttpRequest 객체를 이용하여 Ajax요청을 보낸다.
- 서버는 JSON형태로 요청온 정보만을 담아 순수한 텍스트로 구성된 데이터 문자열을 반환한다.
- 이 문자열을 객체화하는 것을 역직렬화라고 하고 역직렬화를 위해 JSON.parse()를 이용한다.
[출처 : jQuery Ajax & JSON PoiemaWeb](https://poiemaweb.com/jquery-ajax-json)
크롤러
크롤러 : 인터넷에 있는 데이터를 자동 수집하는 프로그램
- 웹 브라우저를 흉내내는 프로그램
정적 크롤링(크롬에서 페이지 소스보기가 가능할 때)
- request: 웹 사이트에 접속, 데이터를 받아오는 역할
- BeautifulSoup: 데이터를 HTML로 해석하는 역할
동적 크롤링
- Ajax : 웹클라이언트에서 서버에 데이터를 요청하는 역할
- JSON : 웹서버로부터 반환되는 데이터
- JSON.parse() : 반환된 데이터를 사용할 수 있도록 객체화 해주는 역할
실습하기
- 목표
- 지속적으로 변하는 인기검색 10위까지의 순위 & 이름 & 현재시가 크롤링해보기
코드
import requests
import json #json import하기
#custom_header을 통해 아닌 것 처럼 위장하기
custom_header = {
'referer' : 'http://http://finance.daum.net/quotes/A048410#home',
'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36' }
#해당 접속 사이트가 아닌 원본데이터가 오는 url 추적. network에서 가지고 온다.
url = "http://finance.daum.net/api/search/ranks?limit=10"
req = requests.get(url, headers = custom_header) #custom_header를 사용하지 않으면 접근 불가
if req.status_code == requests.codes.ok:
print("접속 성공")
stock_data = json.loads(req.text) #json에 반환된 데이터가 들어가 있다.
for rank in stock_data['data']: #stock_data는 'data' key값에 모든 정보가 들어가 있다.
print(rank['rank'], rank['symbolCode'], rank['name'], rank['tradePrice'])
else:
print("Error code")
접속 성공
1 A001000 신라섬유 2350
2 A068270 셀트리온 211500
3 A048410 현대바이오 12650
4 A005930 삼성전자 44650
5 A207940 삼성바이오로직스 338500
6 A020560 아시아나항공 6460
7 A002210 동성제약 20150
8 A007460 에이프로젠 KIC 4000
9 A066570 LG전자 77000
10 A000660 SK하이닉스 80200