7  네이버 스마트스토어 API 연동

7.1 인증 절차

7.1.1 인증 과정 참고

요구사항: Application ID와 Application Secret 필요

위 애플리케이션 ID와 시크릿을 얻는 방법:

#https://private.tistory.com/140#google_vignette

주의:API 그룹의 경우 판매자 정보/주문 판매자/상품/문의 모두 포함

7.1.2 액세스 토큰 생성


import time
import bcrypt
import pybase64
import urllib.parse
import requests

client_id = "xxxxxx"
client_secret = "xxxxx"

def get_token(client_id, client_secret):
    try:
        timestamp = str(int((time.time() - 3) * 1000))
        pwd = f'{client_id}_{timestamp}'
        hashed = bcrypt.hashpw(pwd.encode('utf-8'), client_secret.encode('utf-8'))
        client_secret_sign = pybase64.standard_b64encode(hashed).decode('utf-8')

        headers = {"content-type": "application/x-www-form-urlencoded"}
        data_ = {
            "client_id": client_id,
            "timestamp": timestamp,
            "grant_type": "client_credentials",
            "client_secret_sign": client_secret_sign,
            "type": "SELF"
        }

        # Encode data_ dictionary into a URL-encoded string
        body = urllib.parse.urlencode(data_)

        url = 'https://api.commerce.naver.com/external/v1/oauth2/token'
        print("Request URL:", url)
        print("Request Body:", body)

        res = requests.post(url=url, headers=headers, data=body)
        res.raise_for_status()  # Raise an exception for HTTP errors

        res_data = res.json()
        if 'access_token' in res_data:
            return res_data['access_token']
        else:
            raise ValueError(f'Token request failed: {res_data}')
    
    except Exception as e:
        print(f'Error occurred: {e}')
        return None

st_access_token = get_token(client_id=client_id, client_secret=client_secret)
if st_access_token:
    print(f'Issued token: {st_access_token}')
else:
    print('Failed to obtain token.')

7.2 주요 코드 분석

7.2.1 토큰 발급 함수 (get_token)

def get_token(client_id, client_secret):
    timestamp = str(int((time.time() - 3) * 1000))
    pwd = f'{client_id}_{timestamp}'
    hashed = bcrypt.hashpw(pwd.encode('utf-8'), client_secret.encode('utf-8'))
    client_secret_sign = pybase64.standard_b64encode(hashed).decode('utf-8')

    headers = {"content-type": "application/x-www-form-urlencoded"}
    data_ = {
        "client_id": client_id,
        "timestamp": timestamp,
        "grant_type": "client_credentials",
        "client_secret_sign": client_secret_sign,
        "type": "SELF"
    }

    body = urllib.parse.urlencode(data_)
    url = 'https://api.commerce.naver.com/external/v1/oauth2/token'
    res = requests.post(url=url, headers=headers, data=body)
    res_data = res.json()
    if 'access_token' in res_data:
        return res_data['access_token']
    else:
        raise ValueError(f'Token request failed: {res_data}')
  • 이 함수는 클라이언트 ID와 시크릿을 기반으로 네이버 API에서 access_token을 발급받습니다. bcrypt와 pybase64 라이브러리를 사용해 인증 서명을 생성하고, 이를 바탕으로 POST 요청을 보내 OAuth2 토큰을 받아온다.

7.2.2 Q&A 데이터 가져 오기

if params_bulletin == "Q&A":
    current_datetime = datetime.datetime.now()
    to_date = current_datetime.strftime('%Y-%m-%dT%H:%M:%S.100+09:00')
    from_date = (current_datetime - datetime.timedelta(days=params_interval)).strftime('%Y-%m-%dT%H:%M:%S.100+09:00')

    base_url = "https://api.commerce.naver.com/external/v1/contents/qnas"
    query_params = {'page': 1, 'size': 100, 'fromDate': from_date, 'toDate': to_date}
    headers = { 'Authorization': f"Bearer {st_access_token}" }
    response = requests.get(base_url, params=query_params, headers=headers)
  • 사용자가 선택한 기간(params_interval)에 해당하는 Q&A 데이터를 네이버 API로부터 가져온다. 이 때 fromDate와 toDate를 포함한 URL 매개변수와 함께 GET 요청을 보낸다.

7.2.3 응답 데이터 처리

articles_data = []
if response.status_code == 200:
    data = response.json()
    for qna in data['contents']:
        createDate = qna['createDate']
        question = qna['question']
        answer = qna['answer'] if qna['answered'] == 1 else "답변 필요"
        articles_data.append({'date': createDate, 'question': question, 'answer': answer})
else:
    print("Error:", response.text)
  • API로부터 받은 JSON 데이터를 처리하여, 각각의 Q&A에 대해 질문과 답변을 추출한다. 답변이 없는 경우 “답변 필요”로 표시한다. 이를 DataFrame으로 변환하여 시각화할 수 있다.