끄적거림

[리뷰 크롤링] AppStore 어플 리뷰 가져오기 3 in python(feat.RSS) 본문

Python/Crawling

[리뷰 크롤링] AppStore 어플 리뷰 가져오기 3 in python(feat.RSS)

Signing 2020. 7. 31. 14:46
728x90
반응형

 

2020/07/29 - [Python] - [리뷰 크롤링] AppStore 어플 리뷰 가져오기 1(feat. cURL)

2020/07/30 - [Python] - [리뷰 크롤링] AppStore 어플 리뷰 가져오기 2 in python(feat. cURL)

 


 

1. Trouble Shooting

지난 시간들에서는 appTweak이라는 사이트에서 무료로 제공하는 API를 cURL을 사용하여 app store에서의 어플에 대한 리뷰 데이터를 가져오는 작업을 진행했었다.

 

그러던 중 만난 이슈는 더 많은 리뷰 데이터를 가져올 수 없다는 것! (내가 그냥 실패한 것일 수도 있지만 그래도 내가 노력하고 찾아본바에 의하면 안되는 걸로 마무리 지었다..ㅠㅠ 해결책을 아시는 분이 있다면 댓글로라도..)

 

 

 

2. RSS

그렇게 app store의 리뷰를 포기할 수 없어서 열심히 다른 방법을 강구하던 중, 구세주 같은 stackoverflow에서 해결책을 찾았다.

 

https://stackoverflow.com/questions/1090282/api-to-monitor-iphone-app-store-reviews

 

API to monitor iphone app store reviews

I'm trying to develop a review monitoring system for several iPhone apps I've developed, for instance to email me with the contents of a review when one comes in. (Right now, without an iPhone, I ...

stackoverflow.com

질의 내용은 이랬다.
아이폰 앱 리뷰를 이용해서 모니터링하고 싶다는 이야기였다.

여러 답변 중 가장 상위의 답변은 이렇게 답했다.(참고 url)

  • Apple feedback 쪽에서 rss를 이용하면 가능하다고 한다.
  • 동시에 2개의 데이터 타입으로 데이터를 받을 수 있다.
    • JSON
    • XML
  • 설명에 따르면, JSON이 XML보다 2개의 정보가 더 누락되어있다고 한다.
    • <updated> 정보: 리뷰 날짜를 의미하는 듯
    • <content type="html"> 정보: 사실상 이 정보는 json에도 있는 것 같다.

리뷰를 받기 위한 방법은 다음과 같다.

 

https://itunes.apple.com/HERE-YOU-PUT-THE-CONTRY-CODE/rss/customerreviews/id=PUT-APP-ID-HERE/sortBy=mostRecent/json

 

혹은

 

https://itunes.apple.com/HERE-YOU-PUT-THE-CONTRY-CODE/rss/customerreviews/id=PUT-APP-ID-HERE/sortBy=mostRecent/xml

 

로 브라우저 창에 띄워서 데이터를 볼 수 있다.

 

여기서

  • CONTRY-CODE는 나라코드를 의미하며 한국은 kr이라고 적어주면된다.
  • APP-ID는 지난 시간에 찾았던 application ID를 넣어주면된다.

 

여기서 나의 경우는 다음과 같다.

https://itunes.apple.com/kr/rss/customerreviews/id=1037778235/sortBy=mostRecent/json
https://itunes.apple.com/kr/rss/customerreviews/id=1037778235/sortBy=mostRecent/xml

 

실제 데이터 화면은 아래 그림과 같다.

왼쪽이 JSON, 오른쪽이 XML

내가 보기에는 json보다는 xml이 좀 더 구조화되어 있고 가독성도 좋아보인다.

더불어 중요한 날짜 정보도 있으니 가능하면 xml을 사용하도록 하자.

 

그러면 여기서 내가 원하는 더 많은 정보들이 존재하는가? 지금 상황에서는 그렇지 않다.

 

xml화면의 가장 위에 보면 몇 개의 링크가 더 존재한다.

<link rel="alternate" type="text/html" href="https://apps.apple.com/WebObjects/MZStore.woa/wa/viewGrouping?cc=kr&id=29141"/>
<link rel="self" href="https://itunes.apple.com/kr/rss/customerreviews/id=1037778235/sortBy=mostRecent/xml"/>
<link rel="first" href="https://itunes.apple.com/kr/rss/customerreviews/page=1/id=1037778235/sortby=mostrecent/xml?urlDesc=/customerreviews/id=1037778235/sortBy=mostRecent/xml"/>
<link rel="last" href="https://itunes.apple.com/kr/rss/customerreviews/page=10/id=1037778235/sortby=mostrecent/xml?urlDesc=/customerreviews/id=1037778235/sortBy=mostRecent/xml"/>
<link rel="previous" href="https://itunes.apple.com/kr/rss/customerreviews/page=1/id=1037778235/sortby=mostrecent/xml?urlDesc=/customerreviews/id=1037778235/sortBy=mostRecent/xml"/>
<link rel="next" href="https://itunes.apple.com/kr/rss/customerreviews/page=2/id=1037778235/sortby=mostrecent/xml?urlDesc=/customerreviews/id=1037778235/sortBy=mostRecent/xml"/>
<icon>http://phobos.apple.com/favicon.ico</icon>

이 중에서 rel 값이 first와 last인 부분을 보면 page=1,10이라는 조건이 더 붙는다.

 

이 것을 보고 내가 생각한 것은 "아 리뷰가 1부터 10까지의 페이지가 있구나" 였다.

하지만 생각해보면 좀 이상하긴 하다. 해당 리뷰가 있는 페이지에 접속하면 2천개가 넘는 리뷰가 있는데, 사실상 rss를 사용하여 댓글 수를 확인해보면 몇백개 수준이다.

 

나머지 리뷰 데이터는 어디에 있지..?

 

자 일단은 그런 생각을 하기 전에 이 웹상에 존재하는 데이터를 어떻게 가져올까를 생각해보자.

 

 

 

 

3. XML to DataFrame in python

3.1 Module

먼저, 필요한 모듈은 다음과 같다.

import pandas as pd

import xmltodict
from urllib.request import urlopen
import json
  • DataFrame을 위한 pandas
  • xml을 파싱하기 위한 xmltodict
  • url을 이용하여 웹상이 데이터를 가져올 urllib.request
    • python 3가 아니라면 urllib에서 urlopen이라는 함수만 import하면 된다.
  • xmltodict의 결과물을 dict으로 바꾸기 위한 json

 

3.2 Get Data from URL

다음으로는 해당 url에 접속하여 xml 데이터를 파싱해와야한다.

url = "https://itunes.apple.com/kr/rss/customerreviews/page=1/id=1037778235/sortby=mostrecent/xml?urlDesc=/customerreviews/id=1037778235/sortBy=mostRecent/xml"
response = urlopen(url).read()
response
  • 아까 만들었던 URL을 사용한다.
  • urlopen함수를 사용하여 해당 url이 가지는 값을 가져온다.

 

3.3 Parsing XML

xml = xmltodict.parse(response)
XmlToJson = json.loads(json.dumps(xml))
  • parsing
  • xml to json(dict)

 

 

3.4 Extract Data that I want

res_dict = []

for i in range(len(XmlToJson['feed']['entry'])):
    res_dict.append({
        'DATE' : XmlToJson['feed']['entry'][i]['updated'],
        'STAR' : XmlToJson['feed']['entry'][i]['im:rating'],
        'LIKE' : XmlToJson['feed']['entry'][i]['im:voteSum'],
        'DISLIKE' : int(XmlToJson['feed']['entry'][i]['im:voteCount']) - int(XmlToJson['feed']['entry'][i]['im:voteSum']),
        'TITLE' : XmlToJson['feed']['entry'][i]['title'],
        'REVIEW' : XmlToJson['feed']['entry'][i]['content'][0]['#text']
    })
  • 구조가 다소 복잡하기 때문에 하나 하나 뜯어보면서 진행하는 것을 추천한다.
  • 위의 코드 로직은 이전에서 다뤘던 로직과 동일합니다.

 

3.5 Convert data type & format

res_df['DATE'] = pd.to_datetime(res_df['DATE'], format="%Y-%m-%dT%H:%M:%S-07:00")
res_df['STAR'] = res_df['STAR'].apply(lambda x: int(x))
res_df['LIKE'] = res_df['LIKE'].apply(lambda x: int(x))

res_df
res_df.dtypes
  • DATE는 날짜 객체로 포멧에 맞게 변환해주고
  • 나머지 STAR, LIKE, DISLIKE 같은 경우는 String에서 int형으로 바꿔준다.

 

 

이렇게 하면, 내가 원하는 값들을 모두 가져올 수 있게된다.

이제 이 작업들을 page=1에서 page=10까지 돌려봄으로써 모든 리뷰 데이터를 모아보자.

 

 

 


 

 

 

 

4. Getting whole Data

위의 작업을 모두 반복하고, 추가로 append만 시켜주면 된다.

iter 값은 j로 1~10까지 페이지를 조회하면 된다.

 

res_dict = []
for j in range(1,11):
    url = "https://itunes.apple.com/kr/rss/customerreviews/page=%i/id=1037778235/sortby=mostrecent/xml?urlDesc=/customerreviews/id=1037778235/sortBy=mostRecent/xml" % j
    response = urlopen(url).read()

    xml = xmltodict.parse(response)
    XmlToJson = json.loads(json.dumps(xml))

    for i in range(len(XmlToJson['feed']['entry'])):
        res_dict.append({
            'DATE' : XmlToJson['feed']['entry'][i]['updated'],
            'STAR' : int(XmlToJson['feed']['entry'][i]['im:rating']),
            'LIKE' : int(XmlToJson['feed']['entry'][i]['im:voteSum']),
            'DISLIKE' : int(XmlToJson['feed']['entry'][i]['im:voteCount']) - int(XmlToJson['feed']['entry'][i]['im:voteSum']),
            'TITLE' : XmlToJson['feed']['entry'][i]['title'],
            'REVIEW' : XmlToJson['feed']['entry'][i]['content'][0]['#text']
        })

res_df = pd.DataFrame(res_dict)
res_df['DATE'] = pd.to_datetime(res_df['DATE'], format="%Y-%m-%dT%H:%M:%S-07:00")
res_df.to_csv('../data/IOS_ReviewData.v1.0.csv')

res_df

결과를 보면 2019-07-26일부터 수집이 시작되었는데 그 이전 데이터는 사실 어떻게 구할지 아직 잘 모르겠고, 이슈사항으로 남기고 더 공부를 해야겠다.

 

하지만 이제 어느정도 lifeplus 어플에 대한 리뷰가 쌓였으니 다음 시간부터는 텍스트 마이닝을 진행해보고자 한다.

 

이것으로 Android와 IOS 두 운영체제에서의 어플에 대한 리뷰 데이터를 수집하는 방법에 대해 알아보았다.

 

728x90
반응형
Comments