라프텔 API 뜯어보기 2

아카·2020년 6월 21일
0

라프텔 API(비공식)

목록 보기
2/8

이 포스팅의 내용은 공식적이지 않습니다.

이전 포스팅 바로가기

지난 시간에는 라프텔 API에 직접 요청을 전송해 보고, 받은 결과값이 어떠한 의미인지 대충 알아보았다. 우리의 목적은 각각의 분기마다 방영되었던 애니메이션을 검색하는 것이기 때문에, 개개의 작품 모두를 요청하는 것보다 라프텔 API에 구현된 검색 API를 활용하는 것이 좀 더 합리적일 것이다.
(라프텔 API에 1~45000 사이의 모든 Item ID에 대해서 /api/v1.0/items/{item_id}/detail 요청을 보내면 DDOS로 인식되어 처벌받을 수도 있으니 다른 방법을 고안해보자.)

라프텔 검색 API 명세 파악

search API도 마찬가지의 구조를 가지고 있을 것이. 대충 search/air_year_quarter=2020년 2분기가 아닐까?

/api/v1.0/search/air_year_qurter=2020%EB%85%84%202%EB%B6%84%EA%B8%B0%0A로 h+ttps 요청을 한번 날려보자. 2020%EB%85%84%202%EB%B6%84%EA%B8%B0%0A는 2020년 2분기를 URL encoding한 값이다.

400 Bad Request가 날아온다. 찍은 게 틀렸나보다.

속성 이름을 바꿔가면서 될때까지 하는 방법도 있겠지만, 저번처럼 라프텔 웹의 네트워크를 분석하면 아래와 같은 API 요청을 하면 된다는 것을 알 수 있다.

api/search/v1/discover/?years=2019%EB%85%84%204%EB%B6%84%EA%B8%B0

대충 query string에 우리가 검색하고 싶은 방영년도를 URL 인코딩해 넣으면 될 듯 하다.

그런데 왜 지난 detail은 api/v1.0/items/XXX/detail 형태면서 이번 search는 api/search/v1/discover/XXX 형태일까? 혹시 api/v1.0/items/로도 검색이 가능한걸까?

한번 2019년 4분기 모든 애니메이션을 검색해보자(검색하는 라프텔 API를 사용해보자).

(라프텔 웹에선 기본적으로 별점 순으로 정렬되고, 볼 수 있는 애니메이션만 20건씩 검색되도록 한 것 같다.)

저번처럼 하나하나 살펴보자.

  • count: 이번 분기에 방영된 애니메이션의 총 수로 보인다.
  • next: offset을 20 증가시킨 URL을 반환한다.
    • 쉽게 설명하자면, 우리가 /api/search/v1/discover/?years=2019%EB%85%84%204%EB%B6%84%EA%B8%B0&offset=20 으로 API 요청을 했을 경우, 반환받은 값의 next는 api/search/v1/discover/?years=2019%EB%85%84%204%EB%B6%84%EA%B8%B0&offset=40 이 된다. 즉, 한번 요청에 최대 20개의 애니메이션 정보를 반환받는다는 것이다.
  • results: 검색 결과의 {offset}번째 애니메이션부터 {offset}+20번째의 애니메이션의 정보가 들어있다. 예를 들면, 맨 처음 우리가 요청한 API에는 result가 (자막) 마도조사 2기부터 (무삭제) 이 용사가 ZZANG센 주제에 너무 신중하다까지 있고, offset=20을 넣어 요청한 API의 결과 result에는 노 건즈 라이프 part 1부터 (더빙) 블랙 클로버 2기가 있다.

정리하면,

  • API request Endpoint : /api/search/v1/discover/{애니메이션의 조건}
    • 조건에 offset을 지정하지 않을 시 기본값 0
  • response (JSON)
    • count : 조건에 맞는 애니메이션의 갯수
    • next : request에 지정한 offset+20을 한 URL을 반환받음.
    • offset : 조건에 맞는 애니메이션들 중 반환받을 (최대 20개의) 애니메이션 중 처음 애니메이션의 index

우리가 필요로 하는 것 + 구현하는 방법

우리들이 지정한 분기에 방영한 모든 애니메이션의 정보를 구하는 것이 목적이다. 즉, 만약 우리들이 2019년 4분기의 모든 애니메이션을 반환받고 싶다면 /api/search/v1/discover/years=("2019년 4분기"를 url로 인코딩한 문자열)을 요청하면 되는 것이다.

하지만 라프텔 API는 한번에 최대 20개까지의 애니메이션들의 정보만 반환하므로, offset을 바꿔가면서 요청을 해야 할 필요가 있다. API response에 next값이 다음 요청의 URL을 반환하므로 API response에 next값이 null이 될때까지 반복해서 요청을 보내면 될 것이다.
(수동으로 offset을 20 증가시켜도 무관)

구현

python colab 환경(여기)에서 구현체를 만들어보도록 하자. 우선 새 노트를 만들고, 아래의 코드를 시험삼아 넣어보자.

from urllib.parse  import quote

import requests

laftel_API = 'https://laftel.net/api/search/v1/discover/?years=2019%EB%85%84%204%EB%B6%84%EA%B8%B0'

header = {'laftel' : 'TeJava'}

response = requests.get(url = laftel_API, headers = header)

print(response.text)

위 코드는 laftel_API에 명시된 URL에, 요청시에 헤더를 header 딕셔너리를 사용해서 요청을 보낸 후, 그 결과를 출력하는 코드다. {"count":70,"result"=[...],next="..."}가 출력되면 성공이다. 이제 이를 parsing하는 코드를 구성해보자.

from urllib.parse import quote

import requests
import json

laftel_API = 'https://laftel.net/api/search/v1/discover/?years=2019%EB%85%84%204%EB%B6%84%EA%B8%B0'

header = {'laftel' : 'TeJava'}

response = requests.get(url = laftel_API, headers = header)

json = response.json()

results = json["results"]

for x in results:
  print(x["name"])

실행해보면 20개까지밖에 출력이 되지 않는 것을 확인할 수 있다. 위에서 라프텔 API는 한번 요청에 최대 20개의 애니메이션을 반환한다고 했으므로, 20개를 출력한 후에 만약 next가 null이 아니면 next에 있는 URL로 다시 요청하도록(즉, next가 null이 될때까지 요청 -> 출력을 반복) 코드를 수정해 보자.

from urllib.parse import quote

import requests
import json
import random
import time

header = {'laftel' : 'TeJava'}

laftel_API = 'https://laftel.net/api/search/v1/discover/?years=2019%EB%85%84%204%EB%B6%84%EA%B8%B0'

next = ""

while(True):
  response = requests.get(url = laftel_API, headers = header)  

  json = response.json()

  results = json["results"]

  for x in results:
    print(x["name"])
  
  next = json["next"]
  if (next is not None):
    laftel_API = next
  else:
    break
  time.sleep(random.randint(1, 2))

time.sleep과 random.randint에서는 API 요청간의 시간 간격을 넣기 위해 추가한 구문이다.
위의 코드를 실행하면, 2019년 4분기에 방영된 모든 애니메이션을 화면 출력할 수 있다.

만약 우리가 2019년 4분기가 아니라, 2020년 1분기를 검색하고 싶으면 laftel_API 부분의 2019%EB... 부분을 2020%eb%85%84+1%eb%b6%84%ea%b8%b0로 수정하면 된다. url 인코딩은 파이썬에서 쉽게 할 수 있으므로, 코랩에서 분기를 입력받은 후 입력받은 분기의 애니메이션을 모두 출력하는 코드로 위의 코드를 수정해보자.

from urllib.parse import quote

import requests
import json
import random
import time

boongi = input() # 분기를 입력받는 코드 
encoding = quote(boongi)

header = {'laftel' : 'TeJava'}

laftel_API = 'https://laftel.net/api/search/v1/discover/?years=' + str(encoding)

next = ""
print ("==============================")

while(True):
  response = requests.get(url = laftel_API, headers = header)  

  json = response.json()

  results = json["results"]

  for x in results:
    print(x["name"])
  
  next = json["next"]
  if (next is not None):
    laftel_API = next
  else:
    break
  time.sleep(random.randint(1, 2))

print ("==============================")

위의 코드를 사용하면, 입력받은 분기에 방영된 모든 애니메이션을 알 수 있다.

profile
코딩한량.

0개의 댓글