끄적거림

[리뷰 크롤링] PlayStore 댓글 크롤링하기 in python 2(feat. selenium) 본문

Python/Crawling

[리뷰 크롤링] PlayStore 댓글 크롤링하기 in python 2(feat. selenium)

Signing 2020. 7. 25. 10:32
728x90
반응형

[리뷰 크롤링] PlayStore 댓글 크롤링하기 in python 1(feat. selenium)

[리뷰 크롤링] PlayStore 댓글 크롤링하기 in python 2(feat. selenium)

[리뷰 크롤링] PlayStore 댓글 크롤링하기 in python 3(feat. selenium)

[리뷰 크롤링] PlayStore 댓글 크롤링하기 in python 4(feat. selenium)

[리뷰 크롤링] PlayStore 댓글 크롤링하기 in python 5(feat. selenium)

 


 

지난 시간에 이어서 이번엔 실제로 데이터를 수집해보는 시간을 갖으려고 한다.

 

내가 필요한 데이터는 다음과 같은 총 4개이다.

1. 리뷰 텍스트 데이터

2. 게시 날짜

3. 좋아요 수

4. 별점

 

개발자 도구를 통해 확인해본 결과 구석구석 내가 원하는 정보들이 존재한다.

 

그럼 이 정보를 어떻게 캐내야할까?

 

그 전에 html 구조에 대해 알아보자.

 

 

 

 


HTML은 기본적으로 테그 베이스의 언어로 구성되어 있다.

-- <태그명 속성명="속성값">내용</태그명>
<span class="p2TkOb">2020년 6월 24일</span>

1) 태그명

  • 양 side에 태그를 열어주고 닫아준다. 반드시 쌍으로 존재해야한다.
  • 태그가 어떤 태그인지는 태그명으로 알 수 있다.
  • html, head, title, body, span, div 등 다양한 테그들이 있다.

2) 속성명, 속성값

  • 태그의 속성을 나타낸다.
  • 따옴표("")로 속성값을 처리해준다.

3) 내용

  • 필요한 내용을 텍스트로 입력한다.

 


 

 

 

그러면 내가 원하는 정보들은 어떤 형식으로 이루어져있는지 확인해야한다.

그래야 어떻게 접근해서 어떤 값을 빼올지를 생각할 수 있기 때문이다.

 

 

 

1. 리뷰 텍스트 데이터

첫번째로 가장 중요한 리뷰 데이터이다. 리뷰가 있는 곳의 html 구조를 살펴보자.

리뷰 데이터 구조

"div" 테그에 "jsname"이라는 속성 이름과 "bN97Pc"라는 속성값을 갖고 있다.

그리고 해당 테그 안에 리뷰데이터를 내용으로써 갖고 있다.

우리는 이 내용에 접근해야한다.

 

 

2. 게시 날짜

다음으로 게시 날짜다. 게시 날짜를 굳이 가져오는 이유는 앱 전체에 대한 리뷰 데이터가 필요하면 사실상 필요 없는 데이터이지만 앱의 업데이트 전과 후에 대한 리뷰내용도 중요하다고 생각하기 때문이다.

날짜 데이터 구조

이번에는 "span"테그에 "class"라는 속성과 "p2TkOb"라는 속성값으로 이루어져 있다.

우리가 원하는 날짜 데이터는 내용 부분에 있다.

어떻게보면 1번의 구조와 비슷하다고 볼 수 있다.

 

3. 좋아요 수

좋아요 수는 해당 리뷰에 공감을 하고 있다는 정보이다. 데이터분석을 진행할 때 그만큼 가중치를 주어 분석에 임할 수 있기 때문에 중요한 데이터라고 생각해볼 수 있다.

좋아요 수 데이터 구조

"div" 테그에서 "class", "aria-label" 속성과 "jUL89d y92BAb", "이 리뷰가 유용하다는 평가를 받은 횟수입니다."라는 속성값을 각각 가지고 있다.

실제 좋아요 수의 정보를 담고 있는 데이터는 내용 부분에 존재한다.

위의 두 구조와 속성이 2개라는 부분만 빼면 비슷하다고 볼 수 있겠다.

 

4. 별점

마지막으로 별점 부분이다. 별점은 해당 리뷰가 결과적으로 어느정도인지를 나타내주는 라벨과도 같은 역할을 한다. 때문에 중요한 변수로 생각되어 크롤링 하기로 했다.

별점 데이터 구조

"div" 테그와 "aria-label" 이라는 속성, 그리고 "별표 5개 만점에 1개를 받았습니다."라는 속성값.

또한, "role" 이라는 속성과 "img"라는 속성값을 지니고 있다.

내가 원하는 정보는 다름 아닌 속성값에 존재한다.

위의 3개의 데이터 구조와는 다소 다른 경우라고 볼 수 있다.

 

 

 

 

그러면 이제 데이터를 추출해보자.

 


데이터 추출법

 

먼저, 필요한 모듈을 불러온다.

from selenium import webdriver

 

다음으로, selenium을 이용하여 해당 리뷰 페이지에 접속한다.(전 포스팅 참고)

url = "https://play.google.com/store/apps/details?id=kr.co.zumo.app&showAllReviews=true"
driverPath = "../02.App_review/config/chromedriver_win32/chromedriver.exe"  # driver file path
driver = webdriver.Chrome(driverPath)
driver.get(url)

 

아마 기존의 리뷰 페이지를 직접 들어가보면 뒤에 "showAllReviews=true" 라는 문구는 없을 것이다.

이 문구를 붙여주면 많은 리뷰를 모아 볼 수 있다.

물론 스크롤을 내려서 더 많은 리뷰를 봐야하는 것은 또 다른 처리가 필요하다고 알고 있다.

 

 

그러면 이제 각 정보들을 하나씩 추출해보자.

 

 

 

리뷰 데이터

review = driver.find_element_by_xpath("//span[@jsname='bN97Pc']")
review.text

# <결과>
# '일단 라이프플러스앱만의 BI 부터 맘에 쏙 들고요,
# 보통 마구 광고로 이어지는 각종 홍수처럼 터지는 앱이 아니라 살아가면서 꼭 필요한 것들 ,
# 매일 업데이트 되는, 날 전혀 심심치 않게 하는 궁금한 앱이에요~~♡♡
# 다양한 취향저격 콘텐츠들로 감동과 미소를 짓게 해주시니고맙습니다 !!'

위에서 사용했던 드라이브의 find_element_by_xpath라는 함수를 사용하여 원하는 정보가 있는 데이터 구조에 접근할 수 있다.

 

여기서 xpath는 무엇일까? 

W3C의 표준으로 XML(Extensible Markup Language)문서의 구조를 통해 경로(Path)위에 지정한 구문을 사용하여 항목을 배치하고 처리하는 방법을 기술하는 언어입니다. XML 표현보다 더 쉽고 약어로 되어 있으며, XSL변환(XSLT)과 XML지시자 언어(XPointer)에 쓰이는 언어로 XML 문서의 Node를 정의하기 위하여 경로식(Path Expression)을 사용하며, 수학 함수와 기타 확장 가능한 표현들이 있습니다.

(xpath 참조)

 

xpath 문법

표현 설명
nodename 노드명이 "nodename"인 노드 선택
/ 루트 노드로부터 선택
// 현재 노드로부터 문서상의 모든 노드를 조회
. 현재 노드 선택
.. 현재 노드의 부모노드 선택
@ 현재 노드의 속성 선택

 

이와 같은 문법과 이유로 위의 코드를 해석해보면,

span이라는 태그에서 속성을 선택할 것인데 jsname이라는 속성과 그에 대한 속성값이 'bN97Pc'인 속성을 갖는 노드를 현재 노드로 보고, 그 노드에 대한 모든 노드를 조회하는 것이다.

 

위의 문법에 따라 해석하면 그렇고 사실상 내가 원하는 지점의 내용을 얻을 수 있는 코드이다.

 

이제 어느정도 감이 올 것이다.

 

 

 

 

 

날짜 데이터

date = driver.find_element_by_xpath("//span[@class='p2TkOb']")
date.text

# <결과>
# '2020년 6월 28일'

위와 같은 방식을 적용하면 깔끔하게 날짜 데이터를 추출할 수 있다.

 

 

 

 

 

좋아요 수 데이터

like = driver.find_element_by_xpath("//div[@aria-label='이 리뷰가 유용하다는 평가를 받은 횟수입니다.']")
like.text

# <결과>
# '9'

위에서 구조를 살펴볼 때, 해당 정보의 테그는 두 가지 속성과 속성값을 가지고 있었다.

그 둘 중에서 무엇을 사용해도 상관 없을 것 같았지만, aria-label 속성을 사용하는 것이 더 unique하다고 생각되어 그렇게 했다.

 

 

 

 

별점 데이터

star = driver.find_element_by_xpath("//span[@class='nt2C1d']/div[@class='pf5lIe']/div[@role='img']")
star.get_attribute('aria-label')

# <결과>
# '별표 5개 만점에 5개를 받았습니다.'

문제의 마지막 별점 데이터... 이 정보는 다른 정보들과 다른 곳에 위치해 있었다.

일단, 속성값에 원하는 정보가 있었기에 그 속성값에 접근하는 함수인 element의 get_attribute( )라는 함수를 사용했다.

이 함수를 사용하면 원하는 위치의 속성값을 추출할 수 있다.

 

반면, 해당 속성이 담긴 테그까지 도달하기 위해서 다소 긴 문장의 접근법이 필요했다.

 

왜냐하면, 그냥 div[@role='img']으로 접근하면 이 어플의 총 별점부터 접근하기 때문에 그 상위(부모) 노드부터 접근해서 내려오는 것이 맞다고 생각했다.

 

위에 기입한 것처럼 부모 태그(노드) 다음에 슬래쉬('/')로 구분하여 자식 태그에 접근할 수 있다.

 

그렇게 얻은 element에서 속성값에 접근하여 원하는 정보를 얻었다.

 

 

 

 

 

 

이제 이 정보들을 가공하여 이쁘게 만들어보자.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

http://www.nextree.co.kr/p6278/

 

 

 

728x90
반응형
Comments