서베이몽키 API를 활용하여 설문 응답 내려받기 (feat. 파이썬)

본 포스팅에서는 서베이몽키 API를 활용하여 설문 응답을 내려 받는 파이썬 코드를 소개한다.

들어가기에 앞서…

요즘엔 누구나 온라인 설문을 쉽게 만들고 응답을 수집할 수 있다. 구글 설문지를 사용해서 스프레드시트를 통해 응답을 쉽게 모니터할 수도 있고, MS오피스와 연동이 되는 MS Forms를 쓸 수도 있다. 이런 글로벌 기업들 서비스가 아니더라도 네이버 오피스 폼이나 모아폼 등의 국내 서비스도 얼마든지 대안이 된다.

그러나 나는 서베이몽키를 사용한다. (최근에 Typeform이라는 서비스를 눈여겨 보고 있는데, 나중에 기회가 되면 소개하도록 하겠다.)

왜 굳이 서베이몽키를 사용하는가

사실 서베이몽키는 정말 오래된 서비스다. 그래서 질문이나 페이지를 랜덤 순서로 제시한다거나, 이메일 콜렉터로 개인의 응답을 추척하는 등 다양한 기능을 제공한다. 질문의 형태도 다양하게 구현이 가능하다. 디자인이 좀 구리다는 단점이 있지만 그래도 필요한 기능은 웬만큼 다 있으니 안 쓰기도 아쉬운 서비스다. 우리 회사에서도 설문조사, 진단, 검사 등을 실시할 일이 많기 유료 결제를 해서 쓰고 있다.

내가 서베이몽키를 좋아하는 가장 결정적인 이유는 API를 친절하게 제공하고 있기 때문이다. 아주 초보적인 python 지식과 서베이몽키의 친절한 API 문서 덕분에 설문과 관련한 업무를 꽤 많이 자동화할 수 있었다.

이번 글에서는 설문 응답 데이터를 json으로 내려 받아 엑셀에 정리하는 자동화 코드를 간단히 소개하고자 한다.

1. 준비

우선 ACCESS_TOKEN을 발급 받아야 한다. API를 사용해본 사람이라면 쉽게 할 수 있는 일종의 회원 가입 수준이니 들어가서 직접 발급받자.

https://developer.surveymonkey.com/

그리고 API를 호출할 때는 파이썬 requests 모듈을 사용한다. 일단 인증을 해보자.

import requests

YOUR_ACCESS_TOKEN = "발급받은 값 입력"
s = requests.session()
s.headers.update({
  "Authorization": "Bearer %s" % YOUR_ACCESS_TOKEN,
  "Content-Type": "application/json"
})

2. 응답을 내려받고자 하는 설문조사 ID 확인 (필요한 경우 콜렉터 ID까지 확인)

만들어놓은 설문조사에는 각각 고유의 ID가 있다. 설문조사 ID를 확인하려면 위 코드 아래에 다음과 같은 코드를 작성하자.

url = "https://api.surveymonkey.com/v3/surveys"
response = s.get(url)
surveys = response.json()

print(surveys)

url 부분을 보면 그냥 단순하게 https://api.surveymonkey.com/v3/surveys 라고 되어 있다. 내가 가지고 있는 설문조사들을 보여주는 방식이고, print 해보면 data 안에 href, id, nickname, title 값이 들어 있다. 우선 내려받고자 하는 설문조사의 ID는 이렇게 확인이 된 거다.

콜렉터는 서베이몽키 웹사이트에서 직접 엑셀이나 csv로 응답을 다운 받으면 ID 값이 적혀 있긴 하다. 코드로는 아래와 같이 확인할 수 있다.

survey_id = "설문조사 ID"
url = "https://api.surveymonkey.com/v3/surveys/%s/collectors" % (survey_id)
response = s.get(url)
survey_collectors = response.json()

print(survey_collectors)

3. 응답을 내려받는 코드 작성

서베이몽키는 질문의 형태가 다양하기 때문에, 그리고 응답에 대해 별도의 값이나 가중치를 부여하는 등 값을 내려 받을 수 있는 형태도 다양하기 때문에 웹사이트에서 수치값으로 내려 받는 것과 같은 형태로 변환하려면 정리 과정을 거쳐야 한다. 여기서는 함수로 작성해봤다(1. 응답id를 가중치로 코딩하기). 이어서 응답을 내려 받는 것도 함수 형태로 작성을 했다(2. 응답전체 가져오기).

부끄러운 파이썬 실력이지만 다른 블로그나 웹사이트에서 찾을 수 없는 내용이어서 직접 작성해서 올려 본다. 응답을 내려 받을 때는 url에서 details를 써서 호출해야 한다.

# 1. 응답id를 가중치로 코딩하기 (answer_dict 만들기)
def get_answer_dict(survey_id):

    url = "https://api.surveymonkey.com/v3/surveys/%s/details" % (survey_id)

    response = s.get(url)
    survey_details = response.json()

    answer_dict = {}
    for page in survey_details["pages"]:
        for question in page["questions"]:
            if "answers" in question:
                for choice in question["answers"]["choices"]:
                    if "weight" in choice:
                        answer_dict[choice["id"]] = choice["weight"]
                    else:
                        answer_dict[choice["id"]] = choice["text"]

    return answer_dict

# 2. 응답 전체 가져오기
def get_response_data(survey_id):

    url = "https://api.surveymonkey.com/v3/surveys/%s/responses/bulk" % (survey_id)

    payload = {
    "status" : "completed",
    "page": 1,
    "per_page": 100
    }
    
    response_data = []
    response_id_list = []

    while True:

        response = s.get(url, params=payload)
        responses_bulk = response.json()

        # ["data"]에 값이 없을 때까지 반복
        if responses_bulk["data"] == []:
            break

        answer_dict = get_answer_dict(survey_id)
        
        for data in responses_bulk["data"]:

            response_data_ind = []
            response_data_ind.append(data["id"])
            response_data_ind.append(data["collector_id"])
            response_data_ind.append(data["date_created"])
            response_data_ind.append(data["date_modified"])
            response_data_ind.append(data["ip_address"])
            response_data_ind.extend(["N/A", "N/A", "N/A", "N/A"])

            for page in data["pages"]:
                for question in page["questions"]:
                    for answer in question["answers"]:
                        if answer.get("choice_id"):
                            response_data_ind.append(answer_dict[answer.get("choice_id")])   
                        if answer.get("text"):
                            response_data_ind.append(answer.get("text"))
            
            response_data.append(response_data_ind)

        # 다음 페이지 호출 
        payload["page"] += 1

    return response_data

이렇게 하면 서베이몽키 웹사이트에서 엑셀로 내려받은 것과 같은 형태로 값을 정리할 수 있다. 여기서는 설문조사를 끝까지 완성한 응답만 내려 받는 것으로 코드를 작성했다. (payload에 status를 “completed”라고 넣으면 된다.)

이제 마지막으로 엑셀 시트에 그 값을 붙여 넣는 코드가 필요하다.

4. 엑셀 시트에 값 붙여넣기

파이썬으로 엑셀을 다루는 라이브러리가 여러개 있는데 개인적으로 openpyxl을 추천한다. 일단 가볍고, 쉽다. 웬만한 기능도 다 있다.

3번에서 받아놓은 응답을 리스트 형태로 저장했기 때문에 엑셀에서는 행으로 append를 활용해 하나씩 붙여 넣으면 된다.

survey_id = "설문조사 ID"

# 서베이몽키에서 데이터 받아오기
response_data = get_response_data(survey_id)

from openpyxl import Workbook
wb = Workbook()
ws = wb.active

for line in response_data:
    # 모두 내려받고 싶을 때
    ws.append(line)

    # 특정 콜렉터로 들어온 응답만 내려받고 싶을 때
    # if line[1] == "콜렉터 ID":
    #     ws.append(line)

wb.save('surveydata.xlsx')

여기까지다. API를 잘만 활용하면 각자 하고 싶은 업무를 손쉽게 활용할 수 있으니 기회가 될 때 자신이 활용하는 서비스 API 문서를 꼭 읽어보는 습관을 가지자.

서베이몽키 화이팅(?)

추천 글


“서베이몽키 API를 활용하여 설문 응답 내려받기 (feat. 파이썬)”의 4개의 댓글

  1. 서베이몽키를 파이썬으로 월간리포트 자동화하려고 계속 자료들을 찾아보고 있었는데, 정말정말 감사합니다. 스마트워크로 저노동 고연봉길 걸으시길 바래요 ! !

  2. 안녕하세요, 정보 감사합니다~ 제가 잘몰라서 그러는데 api를 이용해서 다운로드 받으면 실시간으로 데이터가 엑셀에 쌓이는 장점이 있는건가요??

    그냥 액셀로 다운받는것과 api로 다운받는것과 차이가 뭘까요? 제가 너무 몰라서 고견부탁드립니다 ^^

    1. 손으로 내려 받는 거랑 똑같긴 해요…!

      저는 심리검사를 서베이 몽키에 만들어놓아서, 새로 들어온 결과가 있으면 그걸 내려받아 결과를 계산하고 엑셀로 차트를 그려서 보고서를 메일로 쏴주는 것까지 스크립트를 짜놓았어요.

      매번 손으로 하기 번거롭고 실시간 응대가 안 되어서 아예 주기적으로 스크립트가 실행되도록 하고 있습니다. 제가 워낙 게으른 편이라 손으로 똑같은 작업 반복하는 걸 안 좋아하기도 하고요.

      만약 자동화 하고 싶은 게 있으시면 그걸 구현해보시는 게…!

댓글 남기기