brunch

You can make anything
by writing

C.S.Lewis

by 현이 Jul 25. 2022

무작정 웹크롤링 코드리뷰 도전기

파이썬으로 유저 리뷰 수집하기

케이스스터디에서 문제 정의-이슈 발굴을 하기 위해 어떤 데이터를 어떻게 수집하면 좋을지 생각해 보았다. 가장 먼저 생각한 건 실제 사용자의 목소리를 들어봤으면 좋겠다는 거였다. 뉴스 기사에서는 서비스가 목표하는 방향과 대표적인 이슈 사항에 대한 힌트를 얻을 수 있었으나 이들 정보가 실질적인 VOC라고 판단하기는 어려웠다.


그럼 설문조사는? 물론 설문조사는 사용자의 일반적인 생각을 알 수 있는 좋은 툴이다. 하지만 문항을 설계하고 '실제 사용자' 표본을 충분한 수만큼 수집하는 데에는 시간이 걸린다. 이번 스터디는 1~2주 내로 인사이트 도출 단계까지 밟는 것이 목표였기 때문에 설문을 통한 조사가 맞지 않을 수 있다고 생각했다.


그 때 스토어 리뷰가 생각났다. 많은 사용자는 (아마 받아들여지지 않을 수 있다는 사실을 알면서도) 운영측에서 자신의 불편함을 한 번이라도 봐주었으면 하는 마음에 비판적인 리뷰를 올린다. 절대적인 평가 점수는 바이럴 마케팅의 개입으로 인해 신뢰하기 어려울 수 있겠지만, 바로 그렇기 때문에 조사하고자 하는 케이스에 대한 정성 데이터들은 충분한 참고 사항이 될 수 있을 거라 생각했다. 유일한 문제는 데이터 수집을 위해 일차적으로 봐야만 하는 리뷰 양이 매우 많았다는 점이다.


구글 플레이 스토어 리뷰 약 8.74천개 (22.07.24 기준)
애플 앱스토어 리뷰 약 7.5천개 (22.07.24 기준)


22년 7월 24일자 기준으로 내가 원하는 기능의 실제 사용 경험을 찾아내려면 총 약 1만 6천여개의 리뷰를 모두 보아야만 했다. 설상가상으로 두 군데의 스토어 모두 앱 리뷰를 보기에 편한 UI를 제공하고 있지 않았다. 구글 플레이스토어 PC버전에서는 별도의 필터 없이 무한 스크롤을 해야만 했고 앱스토어 PC 버전에서는 기준은 모르겠으나 대표 리뷰 10개만 볼 수 있었다.


[왼쪽] 구글스토어의 무한 스크롤 리뷰, [오른쪽] 애플 스토어의 엄선된(?) 리뷰


이 때 근래 실습하고 있었던 파이썬 웹크롤링이 생각났고... 그래 그럼 리뷰 데이터를 한 번 크롤링해보자는 생각이 났다. 아직 코린이이긴 하나 언어에 대한 기본 지식과 구글링만 있으면 코드를 복붙해서라도(!) 어디든지 갈 수 있다는 걸 경험적으로 터득하는 중이기 때문이다. 그래서 약간의 객기와 함께 반나절의 시간을 야매 코딩에 투자하게 되었다.


우선 내가 참고할 만한 코드를 구글링해보았다. 웹페이지의 html 태그를 파싱해 콘텐츠를 긁어오는 웹크롤링의 원리상 구글 플레이스토어와 앱스토어는 서로 다르게 취급되어야 할 것이다. 나는 다음의 두 블로그를 참고했다.


구글 플레이스토어 크롤러 코드


애플 앱스토어 데이터 수집


애플 앱스토어에서는 HTML로는 리뷰가 10개까지만 제공되고 있기 때문에 더 많은 리뷰를 보고 싶다면 애플에서 제공하는 RSS 피드를 활용해서 직접 XML 파일을 파싱해야 한다. XML 파일로 변환해 파싱을 진행하더라도 리뷰는 한 페이지에 50개씩 최대 10페이지만 뽑아낼 수 있다. 즉 아무리 리뷰 데이터가 많더라도 최대 500개까지 얻어낼 수 있는 것이다(내가 참고한 블로그에서는 최근 등록된 리뷰 순서대로 500개였지만, 다른 분류 기준이 있을 수도 있다. 추가 탐색이 필요하다). 따라서 여기에서는 구글 플레이스토어를 위주로 설명하려고 한다.


이 블로그에서는 구글 플레이스토어 리뷰 데이터 수집을 위해 크게 다음과 같은 과정을 따르고 있었다.

0. 초기 세팅_웹드라이버 설치
1. 패키지 import
2. 무한 스크롤 함수 실행
3. 데이터 크롤링
 - 크롬 드라이버 세팅
 - 페이지 무한 스크롤 자동 진행
 - html 파싱
 - 크롬 드라이버 종료
4. html 데이터 저장
5. 데이터 프레임 변환 및 저장


0. 초기 세팅_웹드라이버 설치

웹크롤링을 위해서는 웹드라이버를 먼저 설치해야 하는데, 웹드라이버는 프로그래밍 언어를 활용해서 웹브라우저를 직접적으로 조작할 수 있게 도와주는 툴이다. 크롬을 통해 웹크롤링을 진행할 것이기 때문에 크롬이 없다면 먼저 크롬을 설치해 준다. 크롬 주소창에 chrome://settings/ 을 입력해 설정 창으로 들어간 후 좌측의 'chrome 정보' 를 누르면 내 크롬 브라우저의 버전을 확인할 수 있다.


그리고 chrome webdriver을 검색하거나 이 사이트에서 해당 버전의 웹드라이버를 다운로드 받으면 된다. 나는 103.0.버전의 브라우저를 사용하고 있기 때문에 103.0 버전을 다운로드 받았다.



1. 패키지 import

파이썬을 실행해서 가장 먼저 필요한 패키지를 import해준다. 크롤링에 필요한 패키지는 selenium과 beautifulsoup이다. 이 두 라이브러리는 약간 기능이 다른데, 먼저 selenium은 클릭, 스크롤 등 웹 브라우저를 동적으로 조작하는 데 쓰고, beautifulsoup은 html과 xml 문서를 파싱하는 데 쓴다. 웹크롤링의 목적이 원하는 웹사이트 내에서 자유롭게 이동하며 원하는 정보를 불러오는 데 있어 보통 두 개를 조합해 사용한다. 그리고 html 파싱 후 데이터프레임을 생성하고 다루기 위해 pandas 라이브러리가 필요하다.


2. 무한 스크롤 함수 실행

8천 7백여개의 리뷰를 내 손가락 대신 끝까지 스크롤해줄 함수를 실행한다. 파이썬을 활용하면 무한 스크롤 동작을 위해 화면을 살짝 위로 스크롤한 뒤 화면을 새롭게 받아오는 것, 더보기 버튼을 클릭하는 것 등 무한 스크롤에 필요한 일련의 동작들을 자동으로 수행할 수 있다.


3. 데이터 크롤링

코드를 따라 크롬 드라이버 세팅을 진행하면 다음과 같은 화면이 뜬다.

실시간으로 크롤링하는 걸 볼 수 있다. 와!


이후 구글 플레이스토어에서 수집할 앱의 도메인 주소를 url 값에 부여해주면 리뷰 페이지가 오픈된다. 이제 아까 작성한 함수를 활용하여 크롤링을 진행한다. 주의할 점이 있는데, 크롤링 도중에 잘 되는지 확인하려 구글 드라이버 창을 직접 조작하지 말자. 크롤링이 종료되며 scroll이 완료되었다는 메시지가 뜨기 때문이다.


이 과정에서 내가 마주한 에러는 크게 두 가지였다.


1) Failed to read descriptor from node connection: 시스템에 부착된 장치가 작동하지 않습니다.(0x1F)

이건 크롬 브라우저가 개발 도구로 사용될 때 일으키는 버그라고 한다. 따라서 드라이버 세팅 과정에서 다음의 코드를 추가하면 해결된다.

chrome_options.add_experimental_option('excludeSwitches', ['enable-logging'])


2) AttributeError: 'WebDriver' object has no attribute 'find_element_by_xpath'

이건 셀레니움이 4.0 버전으로 업그레이드되면서 전반적인 메서드가 바뀐 것이 원인이었다. 코드를 버전에 맞게 수정했더니 해결되었다.

#all_review_button = driver.find_element_by_xpath('/html/body/div[1]/div[4]/c-wiz/div/div[2]/div/div/main/div/div[1]/div[2]/div[2]/div/span/span').click()

수정한 코드

all_review_button = driver.find_element(By.XPATH, '/html/body/div[1]/div[4]/c-wiz/div/div[2]/div/div/main/div/div[1]/div[2]/div[2]/div/span/span').click()


추가. XPath 복사하기

XPath 복사하기

(개발자 도구에서 원하는 요소를 선택한 뒤 우클릭 > copy > copy XPath를 선택하면 경로를 복사할 수 있으므로, html 태그 구조를 하나하나 분석해보는 뻘짓은 하지 말자. 경험담이다.)


무한 스크롤이 끝났으면 전체 웹페이지 소스를 받아온 후 html 파싱을 진행해 주고, 마지막으로 크롬 드라이버를 종료한다.


4. html 데이터 저장, 데이터 프레임 변환 및 저장

추후 추가 작업 없이도 웹 페이지에 있는 전체 데이터를 활용하려면 파싱한 데이터를 html 파일로 저장해야 한다. 이후 리뷰 등록일, 작성자 닉제임, 리뷰 평점, 리뷰 내용 데이터를 데이터프레임 형태로 변환한다.


5.결과

약 2천 5백 70여 건의 리뷰 데이터를 불러왔다. 모든 데이터를 불러온 건 아니었지만 해당 서비스의 최초 출시일과 업데이트 시기, 조사할 예정인 기능에 대해 리뷰를 남겼던 사람의 최소 표본 수(n>=30)가 만족된 점을 고려해 voc를 살펴보기에 적절한 개수의 데이터라고 판단했다.

                    


6. 느낀 점

원하는 데이터를 수집하기 위해 크롤링을 시도했지만 크롤링을 했다고 끝나는 것이 아니다. 추출한 정보는 그야말로 raw data이기 때문에 여기에서 원하는 데이터만 추출하거나 시각화를 하고 싶다면 추가적인 처리가 필요하다. 그리고 조작을 잘못하면 도중에 언제든 데이터 수집이 끊길 수 있다... 이거 자동화를 하려다가 또 다른 일거리만 생길 수도 있겠구나 싶었다. 그리고 코드를 복붙하려 해도 그 코드를 나에게 맞게 쓰려면 로직을 분석하고 수정하는 작업이 필수였다. 그 과정에서 만나는 오류들은 덤이다.


품이 드는 일이라 다른 할 거 많을 때는 좀 짜증이 났지만, 그래도 해결될 때 은근 재밌다. 코드를 활용해서 내가 생각하는 바를 잘 표현해보고 싶어졌다.


그리고 그럼에도 '무한 스크롤' 이라는, 그야말로 아무런 의미 없는 단순작업을 끊임없이 반복하는 일을 기계가 대신 처리해 준다는 것만으로도 어느 정도 메리트가 있는 것 같다. 업무를 더 생산성 있게 진행하고 싶다면 시스템에 언제 어떤 행동을 얼마의 범위만큼 위임할 것인지 구체적이고 섬세하게 고민해야한다는 것도 다시금 느낄 수 있었다.



브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari