소품집

[웹 크롤링] JavaScript로 된 html 불러오기 본문

Web crawling

[웹 크롤링] JavaScript로 된 html 불러오기

sodayeong 2020. 4. 13. 20:42

JavaScript의 이해


  • JavaScript는 객체 기반의 스크립트 언어로 웹 브라우저의 경우 엔진이 인터프리터의 역할을 수행
  • JavaScript는 HTML 및 CSS와 함께 사용됩니다. HTML은 웹 페이지의 전체 틀을 잡고, CSS는 개별 요소의 디자인 맡음
  • JavaScript는 사용자와의 상호작용을 통해 웹 페이지에서 보여주는 콘텐츠를 동적으로 제어함

 

 

AJAX와 XHR


  • AJAX는 JavaScript 라이브러리 중 하나이며, 'Asynchronous JavaScript And XML'(비동기 JavaScript 및 XML)의 머리글자 입니다. (비동기처리란? 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고, 순차적으로 다음 코드를 먼저 실행하는 자바스크립트의 특성. 예를들어 은행은 동기처리, 카페는 비동기 처리)
  • AJAX는 HTTP 요청 대신 XHR(XHR HTTP Request) 객체를 사용함
  • AJAX는 웹 서버와의 통신을 통해 JSON 및 XML 형태의 데이터를 주고 받음. 하지만 JSON이 가장 편리하게 사용되는 형태

 

 

 

JavaScript + GET 방식 실습

: Naver Blog Main 실습

https://section.blog.naver.com/BlogHome.nhn?directoryNo=0¤tPage=1&groupId=0


  1. 블로그 메인 가져오기
# 필요 패키지 적용
library(httr)
library(rvest)
library(dplyr)
library(tidyverse)

#URL 저장
URL <- 'https://section.blog.naver.com/BlogHome.nhn?directoryNo=0&currentPage=1&groupId=0'

#httr 요청
res <- GET(url=URL,
           query=list(directoryNo=0,
                      currentPage=1,
                      groupId=0))
print(res) # 찍어봤을 때 Status가 200이면 응답이 잘 된것.

 

  2. 블로그 제목 추출하기

res %>%
  read_html() %>%
  html_nodes(css='strong.title_post') %>%
  html_text()

위를 시행하면, 해당 HTML 요소가 없다는 것을 알 수 있음.

그럼 어떻게 블로그 제목을 추출할 수 있을까요?

 

 

 

네이버 블로그 메인 화면


 

네이버 블로그 메인 화면으로 접속한 뒤, 네트워크 탭의 Doc로 이동하면 두 개의 파일이 보입니다. 그 중 첫 번째 파일의HTTP를 요청해 볼게요.

 

XHR에는 여러 개의 파일이 보이는데, 그중에서도 'DirectoryPostList.nhn' 파일이 포스팅 헤드명을 찾아올 수 있을 것 같네요.

여기서 참고해야할 점은, XHR에서 관련 파일을 찾는 방법은 정해져 있는 게 아닌, 개별 파일을 프리뷰로 확인하고 '찾는 파일과 관련 되어 있는 가?'를 판단해야 합니다.

 

 

 

자바 스크립트가 사용된 것으로 확인됩니다.

자바 스크립트가 활용된 것을 알았으니 Network→XHR 탭에서 관련 파일을 찾아서 http를 요청할게요.

 

 

# http 요청

res <-GET(url='https://section.blog.naver.com/ajax/DirectoryPostList.nhn?directorySeq=0&pageNo=1',
          query=list(directorySeq='0',pageNo='1'))
print(res)

잘못된 요청이라고 뜨네요. 그러면 요청 헤더 중 referer을 추가해볼까요?

 

 

 

 

 

요청 헤더 중 referer 추가하기


  • referer이란?
  • 웹 페이지 간 이동할 때 남는 흔적을 의미함.
  • 하이퍼링크를 통해 어떠 한 사이트에서 다른 사이트로 이동한다고 했을 때, 새로 열린 사이트에이전 사이트의 URI를 전송하는데 이것이 referer
  • HTTP 요청 시, 웹 서버가 요청 헤더에 referer를 요구하는 경우가 있음

Request Headers에서 referer을 찾아 줍니다.

 

 

 

 

HTTP 요청 시 referer 추가하기


referer은 GET() 함수에 add_headers()로 추가할 수 있습니다. 
res ← GET(url='해당url',add_headers(referer='해당 referer'))
# referer를 다시 찾아서 설정
# URL 부분까지만 가져와도 됨!!

ref <- 'https://section.blog.naver.com/BlogHome.nhn'
res <-GET(url='https://section.blog.naver.com/ajax/DirectoryPostList.nhn',
          query=list(directorySeq='0',
                     pageNo='1'),
          add_headers(referer=ref))
print(res)

이번엔 제대로 된 응답을 받은 걸 확인할 수 있었습니다. 그리고 JSON 데이터로 받은 것도 확인할 수 있네요. 그러면 JSON에서 데이터를 추출하면 되는거겠죠?

JSON에서 데이터를 추출하는 방식은 다음과 같습니다. key-value 패턴으로 표현되고, 오브젝트를 전달하기 위해 사람이 읽을 수 있는 텍스트를 브라우저/서버 통신에 사용됩니다.


 

 

JSON에서 데이터 추출하기


  • JSON 타입은 rvest 함수들을 사용하지 않고 간단하게 처리할 수 있음.
  • fromJSON() 함수만으로 res 객체에 포함된 JSON 데이터를 추출함
  • 리스트 객체로 저장됨=
  • ")]}',"을 제거해야 fromJSON() 함수가 제대로 작동함
json <-res %>%
  as.character()%>%
  str_remove(pattern="\\)\\]\\}\\',") %>%
  fromJSON()

blog <-json$result$postList
str(blog)
  • 총 100개의 블로그가 제공되며, 한 페이지당 10개씩 수집할 수 있습니다.
  • 페이지를 1~100까지 바꿔가며 데이터를 저장하면 됩니다.

 

 

728x90
Comments