(1)에 이어서..
< 키워드별 상품 개수 수집 >
- 키워드별 상품 개수를 CSV 파일로 저장하는 함수 shop_cnt_to_cvs() 정의
import time
from pathlib import Path
import pandas as pd
from tqdm import tqdm
from step_1_1 import OUT_DIR
from step_1_2 import query_naver_shop
from step_2_2 import OUT_2_2
OUT_2_3 = OUT_DIR / f"{Path(__file__).stem}.csv"
def shop_cnt_to_csv() :
df_raw = pd.read_csv( OUT_2_2 ) # CSV 파일에서 데이터 프레임 생성
kwd_list = df_raw["키워드"].to_list() # 키워드 열을 리스트 타입으로 변환
item_cnt = []
with tqdm( total = len(kwd_list)) as pbar :
for kwd in kwd_list :
resp = query_naver_shop( query = kwd )
total = resp.get( "total", 0 )
item_cnt.append( { "키워드" : kwd , "상품수" : total } )
time.sleep(0.5) # 0.5 초간 일시정지
pbar.set_description(kwd) # 진행 표시줄 메시지 수정
pbar.update() # 진행 표시줄 업데이트
df_raw = pd.DataFrame( item_cnt )
df_raw.to_csv( OUT_2_3 , index = False )
if __name__ == "__main__" :
shop_cnt_to_csv()

< 키워드별 경쟁 강도 분석 >
- 키워드별 상품 개수 데이터에 키워드별 검색수 데이터를 결합하여 경쟁 강도를 분석할 수 있다.
from pathlib import Path
import pandas as pd
from step_1_1 import OUT_DIR
from step_2_2 import OUT_2_2
from step_2_3 import OUT_2_3
OUT_2_4 = OUT_DIR / f"{Path(__file__).stem}.csv"
def comp_lev_to_csv() :
df_kwd = pd.read_csv( OUT_2_2 ) # 정제 처리된 연관 키워드
df_shop = pd.read_csv( OUT_2_3 ) # 키워드별 상품 개수
df_merged = pd.merge( df_kwd , df_shop , left_on = "키워드" , right_on = "키워드" )
df_merged["경쟁강도"] = ( df_merged["상품수"] / df_merged["검색수M"] ).round(6)
df_filtered = df_merged.filter(["키워드", "검색수M", "클릭수M", "클릭률M", "상품수", "경쟁강도"])
df_sorted = df_filtered.sort_values( "경쟁강도", ascending=False )
df_sorted.to_csv( OUT_2_4 , index = False )
if __name__ == "__main__" :
comp_lev_to_csv()

- 키워드별로 경쟁강도가 내림차순으로 정렬된 csv 파일
- ‘나이키신발’ 키워드의 경쟁강도가 136으로 매우 높은 수준임을 알 수 있음
< 연관 키워드 경쟁 강도 분석 웹 앱 만들기 >
import pandas as pd
import streamlit as st
from step_2_1 import rel_kwd_to_csv
from step_2_2 import data_cleaning
from step_2_3 import shop_cnt_to_csv
from step_2_4 import OUT_2_4, comp_lev_to_csv
def init_page() :
st.set_page_config( layout = "wide" )
st.header( "jiwoo's 연관키워드 경쟁강도 분석" )
if "keywords" not in st.session_state :
st.session_state[ "keywords" ] = ""
with st.form( key = "my_form" , border = False ) :
col_1, col_2 = st.columns( [ 3 , 1 ] ) # 3 : 1 비율의 두개의 열 위젯 생성
with col_1 :
st.text_input( "키워드", key = "keywords" , label_visibility = "collapsed" )
with col_2 :
st.form_submit_button( label = "분석하기" , use_container_width = True )
def analyze_keywords ( keywords : str = None , event : int = None ) :
rel_kwd_to_csv ( keywords = keywords , event = event )
data_cleaning() # 데이터 정제
shop_cnt_to_csv() # 키워드별 상품 개수 수집
comp_lev_to_csv() # 키워드별 경쟁강도 분석
def print_dataframe( keywords : str = None ) :
if keywords :
with st.spinner( "잠시만 기다려주세요..." ) :
analyze_keywords( st.session_state[ "keywords" ] ) # 연관 키워드 분석
df_result = pd.read_csv( OUT_2_4 ) # 분석 결과를 데이터 프레임으로 변환
st.dataframe( df_result , use_container_width = True ) # 데이터 프레임 출력
if __name__ == "__main__" :
init_page()
keywords = st.session_state["keywords"]
print_dataframe( keywords = keywords ) # 데이터 프레임 출력
streamlit run '파일경로'



< 데이터프레임 시각화 하기 >
- 웹 앱에서 데이터프레임의 인덱스 표시를 숨기고, 숫자 표시 부분을 막대 그래프로 바꿔서
- 수치가 전체 데이터에서 어느정도를 차지하는지 쉽게 확인할 수 있도록 시각화 하기
import pandas as pd
import streamlit as st
from streamlit.column_config import NumberColumn, ProgressColumn
from step_2_4 import OUT_2_4
from step_3_1 import analyze_keywords, init_page
def print_dataframe_with_style( keywords : str = None , event : int = None ) :
if keywords or event is not None :
with st.spinner( "잠시만 기다려주세요..." ) :
analyze_keywords ( keywords = keywords , event = event ) # 연관 키워드 분석
df_result = pd.read_csv( OUT_2_4 ) # 분석 결과를 데이터프레임으로 변환
max_values = df_result.max().to_dict() # 열별 최댓값을 딕셔너리로 변환
st.dataframe(
df_result ,
use_container_width = True , # 너비 최대화
hide_index = True , # 데이터프레임 인덱스 숨김
column_config = { # 열별 스타일 설정
"검색수M" : ProgressColumn( width = "small" ,
max_value = max_values.get( "검색수M" , 1 ) ,
format = "" ) ,
"클릭수M" : ProgressColumn( width = "small" ,
max_value = max_values.get( "클릭수M" , 1 ) ,
format = "" ) ,
"클릭률M" : ProgressColumn( width = "small" ,
max_value = max_values.get( "클릭률M" , 1 ) ,
format = "" ) ,
"상품수" : ProgressColumn( width = "small" ,
max_value = max_values.get( "상품수" , 1 ) ,
format = "" ) ,
"경쟁강도" : NumberColumn( format = "%.2f" ) ,
},
)
if __name__ == "__main__" :
init_page()
keywords = st.session_state["keywords"]
print_dataframe_with_style( keywords = keywords )

- 열별로 최댓값 대비 실제 결괏값을 진행 표시줄로 시각화해서 경쟁강도를 직관적으로 파악할 수 있다.
'짧은 호흡 > Python' 카테고리의 다른 글
| [파이썬] Ch.13 (2) gemma/llama 챗봇 + 기사 번역 웹 (0) | 2026.07.16 |
|---|---|
| [파이썬] Ch.13 (1) gemma2로 챗봇 웹 앱 만들기 (0) | 2026.07.13 |
| [파이썬] Ch.8 (1) 쇼핑 키워드 데이터 수집 + 정제 (0) | 2026.07.09 |
| [파이썬] Ch.5 (2) 광학 문자 인식 + DeepL API 번역 (0) | 2026.07.07 |
| [파이썬] Ch.5 (1) 광학 문자 인식 + 웹 앱 만들기 (0) | 2026.07.04 |