안녕, 세상!

동적페이지 크롤링(스크래핑) 본문

It공부/Data science

동적페이지 크롤링(스크래핑)

dev_Lumin 2021. 2. 5. 19:39

( 본 글의 크롤링은 크롤링이라기보다 스크래핑이 더 가깝습니다.

 보통 사람들이 스크래핑도 크롤링이라고 부르는 경향이 있는 것 같습니다.

 저도 일단 대중적인 표현으로 크롤링이라고 표현하겠습니다만

 이 부분을 염두해주고 봐주시면 감사하겠습니다. )

 

 

최근 웹페이지 부분이 Js로 변경이 되며, 일반적인 크롤링이 되지 않은 경우가 많습니다.

우선 동적 페이지가 무엇인지 파악해보겠습니다.

 

(본 실습의 환경은 반드시 크롬에서 이뤄져야 합니다.)

 

(1) 동적 페이지란 

네이버 페이지의 일부분을 예를 들어서 설명하겠습니다.

빨간 상자 부분의 카테고리 부분을 클릭을 하게 되면 해당 카테고리에 대한 정보가 제공되면서

밑의 UI부분이 다른 화면으로 전환됩니다.

그러나 카테고리 목록 버튼을 눌러서 다른 화면으로 전환됨에도 불구하고,

Url의 변화는 없습니다.

 

이렇게 Url변화 없이 동적으로 반응하는 페이지를 동적 페이지라고 합니다.

( 실시간 검색어, 특정 카테고리 등 들이 있습니다. )

그렇다면 앞서 크롤링을 할 때 url을 기반으로 웹의 html혹은 json파일로 접근하여 데이터를 추출하였는데

다음과 같은 경우는 url이 변하지 않으니 난감합니다.

하지만 방법이 있습니다.

이 또한 크롬의 개발자 도구를 사용한다면 어느 정도 해결할 수 있습니다.

 

(2) 동적 페이지 크롤링

크롤링을 하는 이유는 사용자가 필요한 데이터를 가져오기 위해서입니다.

유의미한 데이터가 있다고 판단한 NaverLab에 한 번 들어가서 크롤링을 시도해보겠습니다.

datalab.naver.com/ 

 

네이버 데이터랩

네이버의 검색 트렌드 및 급상승검색어 이력, 쇼핑 카테고리별 검색 트렌드 제공

datalab.naver.com

하지만 다음과 같이 카테고리를 눌러서 변경을 해도 Url이 변하지 않습니다.

바로 동적 페이지입니다. 

 

동적 페이지의 크롤링은 개발자 도구를 사용하면 할 수 있다고 했습니다.

(전 글에서 기본적인 개발자 도구로 크롤링하는 방법 있음)

 

개발자 도구를 실행시키고 이번에는 network를 누른 상태에서

동적 페이지 부분을 선택을 해보겠습니다. (필자는 패션잡화 선택)

그럼 다음과 같이 해당 동적 페이지에 대한 파일이 나옵니다.

 

동적 페이지 파일을 누르면 다음과 같이 나옵니다.

바로 위의 General의 Request URL이 해당 동적 페이지의 요소에 대한 url 주소입니다.

이제 이를 이용해 크롤링을 할 수 있는 것입니다.

또한 동적 페이지를 크롤링할 때 두 가지 정보가 추가적으로 필요할 수 있습니다.

 

User-aget : 사용자 컴퓨터를 지칭하는 주소

referer : 요청 헤더로 현재 요청된 페이지의 링크 이전의 웹 페이지 주소

 

두 개의 헤더 정보도 헤더로 함께 requests 하면 됩니다.

 

이제 코드로 직접 크롤링을 해보겠습니다.

 

 

(3) 코드

( 해당 코드 실행환경은 jupyter notebook입니다. )

import numpy as np
import pandas as pd
import requests # 크롤링에 사용하는 패키지
from bs4 import BeautifulSoup # html 변환에 사용함
import time
import json
# 카테고리 데이터 가져오기
url = 'https://datalab.naver.com/shoppingInsight/getKeywordRank.naver?timeUnit=date&cid=50000001'

# 헤더정보 필요
header = {
    'user-agent': '본인url을쓰기',
    'referer': 'https://datalab.naver.com/'
}

response = requests.post(url, headers=header)
if response.status_code == requests.codes.ok:
    print('접속성공')
response.text

다음과 같이 동적 페이지 부분의 정보가 잘 크롤링되는 것을 확인할 수 있습니다.

 

url을 보면 마지막에 50000001로 되어 있는 것을 확인할 수 있는데,

위에 있는 목록인 '패션의류'는 50000000이고,

아래 있는 목록인 '화장품/미용은 50000002입니다.

이렇게 패턴이 있기 때문에 반복문을 이용해서 동적 페이지의 여러 카테고리들을 한 번에

크롤링 할 수 있습니다.

 

일단은 '패션잡화' 부분만 크롤링 하겠습니다.

 

추가로 response.status_code라는 것을 사용했습니다.

. status_code는 request를 받은 내용에 대한 상태를 나타냅니다.

requests.code.ok를 통해서 requests 한 데이터를 잘 받아오면 '접속 성공'이라는 것을 출력하도록 했습니다.

 

또한 requests로 요청할 때 이번에는 post로 요청을 했습니다.

전 글에서는 get으로 요청을 했는데 위의 개발자 도구를 통해서 network를 보았을 때,

request method가 post이기 때문입니다.

( 사실 당장에 get으로 해도 데이터를 추출하는데 문제는 없지만 안 되는 경우도 있으며 둘은 분명한 차이가 있기 때문에 해당 request method로 설정하는 것이 좋음)

그렇다면 get과 post의 차이는 무엇일까요?

HTTP

http는 웹 상에서 클라이언트와 서버 간에 요청/응답으로 데이터를 주고받을 수 있는 프로토콜입니다.

클라이언트가 http 프로토콜을 이용하여 서버에게 요청을 하고(requests),

그에 맞는 응답을 서버는 클라이언트에게 전송합니다.

이때 http 요청에 포함되는 http 메소드

서버가 요청을 수행하기 위해 해야 할 행동을 표시하는 용도로 사용하는데

http 메소드 중 getpost가 있습니다.

 

Get

get은 서버로부터 정보를 조회하기 위해 설계된 메소드입니다.

get은 요청을 전송할 때 필요한 데이터를 Body에 담지 않고, 쿼리 스트링을 통해 전송합니다.

url의 끝에 '?'와 함께 이름과 값으로 쌍을 이루는 요청 파라미터를 쿼리 스트링이라고 합니다.

만약 요청 파라미터가 여러 개이면 '&'로 연결하여 요청합니다.

쿼리 스트링을 사용하게 되면, url에 조회 조건을 표시하기 때문에 특정 페이지를 링크하거나 북마크 할 수 있습니다.

 

Post

post는 리소스를 생성/변경하기 위해 설계되었기 때문에 get과 달리 전송해야 될 데이터를 

http 메시지의 body에 담아서 전송합니다.

HTTP 메시지의 Body는 길이의 제한 없이 데이터를 전송할 수 있습니다.

그래서 POST 요청은 GET과 달리 대용량 데이터를 전송할 수 있습니다

이처럼 POST는 데이터가 Body로 전송되고 내용이 눈에 보이지 않아 GET보다 보안적인 면에서 안전하다고 생각할 수 있지만,

POST 요청도 크롬 개발자 도구, Fiddler와 같은 툴로 요청 내용을 확인할 수 있기 때문에

민감한 데이터의 경우에는 반드시 암호화해 전송해야 합니다.

 

참조 : ( GET과 POST의 차이 | 기록하기 (hongsii.github.io)

( 좀 더 자세한 내용은 해당 링크에서 참조 : 자세히 다루니 읽는 게 좋음 )

 

 

 

위의 파일을 json형태임을 알 수 있습니다.

이에 따라 json 디코딩을 해서 데이터를 추출할 수 있습니다.

data = json.loads(response.text) # json파일을 리스트로 받아옴
data

 

저는 이 중에서 나이키 대표적인 예쁜 단화 데이브레이크를 추출해보겠습니다.

(예전에 이쁜 색상들은 리셀로 적당한 사이즈도 구하기 쉽지 않은.......)

 

data[0]['ranks'][1]['keyword']

이렇게 동적 페이지에서도 원하는 데이터를 인덱싱을 통해서 뽑아낼 수 있습니다.

 

동적 페이지는 주로 json인 경우가 많습니다.

물론 html인 경우도 있습니다.

 

또한 json은 쉽게 pandas의 DataFrame 형태로 쉽게 변환이 가능합니다.

json 형태 파일을 pandas로 바꾸기 위해서 다음을 import 합니다.

# 위의 json을 배열형태로 바꾼 이러한 파일들을 pandas의 dataframe으로 변환 가능
# json이 판다스로 바꾸기 쉬워서 좋음
from pandas.io.json import json_normalize
df=pd.DataFrame(data[0])
df

이렇게 쉽게 Dataframe 형태로 바꿀 수 있습니다.

 

Comments