텀블벅 평균 펀딩기간 구하기 삽질

텀블벅 평균 펀딩기간 구하기 삽질

나는 이걸 왜 하는가?

  • 제품이 나와서 이제 텀블벅에 업로드만 하면 되는 상황인데 가격이나 기간 등의 디테일한 의사결정이 필요했다. 돈벌자고 하는 게 아니라서 가격은 제작비만 건질 수준으로 책정했는데, 펀딩 기간은 얼마나 길게 잡아야 할지 감이 잘 오지 않았다.
  • 마침 웹스크래핑도 배웠겠다, 우리와 비슷한 제품들 중 펀딩에 성공한 프로젝트들의 평균 펀딩기간을 한 번 구해보기로 했다.

어떻게 할 것인가?

  1. 텀블벅에 우리 제품과 비슷한 제품들을 추리고, 그 제품들 중 성공한 프로젝트들의 정보를 받아온다.
  2. 각 프로젝트에서 내가 필요한 정보들만 취해서 딕셔너리로 만들고, 그 딕셔너리를 리스트에 담아 눈으로 볼 수 있는 파일로 만든다.
  3. 프로젝트 정보 중 펀딩 기간을 추출해서 모두 더해 평균을 낸다.

삽질의 과정

텀블벅 서버의 400 응답

  • 상황: 텀블벅 페이지의 검색 필터가 잘 되어있어서 우리 제품의 카테고리에 맞는 프로젝트 중 성사된 것들만 볼 수 있는 결과 페이지에 접속해 요청 토큰을 따왔다. 텀블벅 검색결과
  • 문제: 순조롭게 서버로부터 데이터를 받아와 파싱하…려고 했는데 수업시간에 배운 cURL로 request를 받아도 400의 response가 왔다.
  • 해결: 아직 내 역량으론 해결할 수 있는 부분이 아니라서 빠르게 포기하고 꼼수를 썼다.
  • 꼼수: 브라우저에서 받은 json형태의 응답 값을 개발자도구에서 복사해서 갖다 썼다.

스크롤해야 나타나는 아이템들

  • 상황: 텀블벅은 스크롤을 내려야 그 다음 프로젝트들이 로드되는데, 한 번에 다 오는 것도 아니고 18개씩 로드된다. 왜 하필 18개인지는 나의 마음이 대변한다.
  • 문제: 이런 역동적으로 받아오는 데이터를 작업할 수 있는 실력이 아니라는 것이 문제
  • 해결: 이 또한 빠른 포기와 더불어 옛날 자료는 큰 의미가 없기에 최신데이터 일부만 가져오는 걸로 결정
  • 꼼수: 검색 시 바로 나타나는 18개의 프로젝트 + 한 번 스크롤 내렸을 때 나타나는 18개, 총 36개만 따왔다. 스크래핑이 아니라 json형태 응답값을 개발자도구에서 복붙했다.

datetime 모듈과 timedelta 객체의 활용

  • 상황: 프로젝트 업로드 시각과 프로젝트 마감 시각이 있으니 이걸 뺄셈 연산으로 프로젝트 펀딩 기간을 계산하려 했는데, json 형태라서 다 string 자료형이었다.
  • 문제: 그냥 string도 아니고 연월일시분초에다가 time zone까지 나와있는 녀석이라서, 문자열을 타입캐스팅한다고 해도 이걸 뺄셈을 어떻게 할수있을런지 당황.
  • 해결: 분명 json형태 전체를 적절한 형태로 바꿔주는 게 있을것 같긴 한데 일단은 검색. ‘string to date python’을 구글링하고 python docs의 datetime 파트를 파보았더니 다음과 같은 것들을 알게 되었다.
    • datetime 모듈에서 시간 문자열을 datetime 객체로 바꿔주는 메서드 datetime.fromisoformat(str): 이제 프로젝트의 시작시간과 끝시간은 문자열이 아니라 적어도 시간으로써 유효한 형태의 datetime 객체가 되었다.
    • 혹시 이거 뺄셈도 되는지 한번 빼보았더니 유레카. 뺄셈도 먹힘: datetime 객체의 뺄셈 결과물은 특정 시각을 나타내는 게 아니라 두 날짜나 시간의 차이인 기간을 나타내는 timedelta라는 객체라는 것도 알게되었다. 혹시나 해서 더하기도 해보고 나누기도 해봤는데 다 먹힌다. timedelta 객체는 그냥 숫자와 비슷하다고 보면 되겠구나.
    • 이제 평균을 구할 수 있게 되었다. 평균 구하는 더 쉬운 방법이 있을 것 같긴 한데 난 무식하니까 그냥 reduce 함수로 다 더하고 분모로 리스트의 크기를 잡아 나눠주었다. 평균값 26일이라는 게 터미널에 찍혔을 때 너무 신나서 소리지를 뻔.평균 산출결과

File로 결과물 출력

  • 상황: 텀블벅에서 긁어온 데이터를 필요한 것만 추려서 딕셔너리에 담긴 했는데, 이걸 csv파일로 만들어야 엑셀에서 보기가 편할 것이다.
  • 문제: 각 프로젝트 딕셔너리의 키값들을 따로 위로 빼주는 header을 어떻게 하는지 모름. TIL을 다시 뒤져봤지만 csv에서 읽어서 json으로 출력하는 것만 배웠고 dictionary같은 걸 csv로 출력하는 건 배우지 않았었네…
  • 해결: 이럴 땐 구글링이다. ‘dictionary python to csv’라고 치면 전세계의 친절한 개발자들이 다 알려준다.
    • How to save a Python Dictionary to CSV File?
    • 딕셔너리를 csv로 출력할 경우 csv.DictWriter({파일명}, fieldnames={키값들의 리스트})로 출력할 데이터를 설정해주어야 하는데, 키값들, 즉 header는 파일 출력 시 writeheader라는 메서드를 호출하여 추가해줘야 한다.
    • 그 다음에 각 딕셔너리를 writerow 메서드로 한줄씩 추가해주면 만고땡.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
projects = []

for data in data_list:
project = dict()
project['Title'] = data['title']
project['Description'] = data['shortDescription']
project['Achievement'] = float(data['achievementRate'])
project['Number of Funders'] = data.setdefault('pledgesCount', 0)
project['Total Fund'] = data['pledgedAmount']
project['Funding Goal'] = data['fundingGoalAmount']
project['Start Date'] = datetime.fromisoformat(data.setdefault('publishedAt',0))
project['End Date'] = datetime.fromisoformat(data.setdefault('endedAt',0))
project['Duration'] = project['End Date'] - project['Start Date']
project['Link'] = data['permalink']
projects.append(project)

header = projects[0].keys()

with open('projects.csv', 'w', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=header)
writer.writeheader()
for project in projects:
writer.writerow(project)
  • 이렇게 하면 csv파일이 나오고 다음과 같이 영롱한 데이터를 엑셀로 로드할 수 있다.
csv 결과물

기타 자잘한 삽질들

  • 문제: 몇몇 프로젝트 딕셔너리의 특정 프로퍼티가 아예 존재하지 않아서 에러가 떴다.
  • 해결: 변수에 설정할 때 setdefault로 프로퍼티가 없을 때의 기본값을 넣어주었다.

데이터에 기반한 의사결정의 과정

  • 성공한 프로젝트들의 펀딩기간 평균은 26일 17시간이다.
  • 우리가 원래 하려고 했던 펀딩기간이 40일이라서 조금 길다고 생각했는데 사실 이런 근거 없이도 원래도 좀 길다는 것이 나의 의견이었다. 하지만 근거가 있다면 더 목소리 키워 주장할 수 있게 된다.
  • 물론 이렇게까지 안했어도 동료팀원은 내 의견을 수용해주었을 것이지만, 데이터에 기반한 의사결정을 했다는 점에 의의가 있다.의사결정카톡

느낀 점

  • 처음으로 학습이나 숙제가 아닌 내가 필요한 것을 따오는 코드를 짜봤다. 물론 손으로 하나하나 하는 게 더 빨랐을 정도로 단촐한 데이터이긴 하지만 배운 걸 써먹을 수 있어서 희열이 느껴졌다.
  • 그리고 이를 활용해서 의사결정을 했다는 것도 너무나 의미있는 일이었다. 한두시간 정도 걸린 것 같은데 오늘 종일 집중 안되다가 막판에 뭐라도 해내서 너무 기쁘다.

TO DO

  • Response 400 문제 해결하기
  • json 형태의 string을 모두 파이썬 형태로 바꾸는 것 알아보기
  • 스크롤 내렸을 때 나오는 데이터 가져오는 법 선생님한테 물어보기.