파이썬에 대해 배우게 되면 단순히 계산이나 분석에 사용하는 것 뿐만아니라 생산성을 늘릴 수 있는 다양한 활용이 가능해진다.
파이썬의 기본 문법에 대해서 익히고 나서
Selenium 기반 크롤링과 FastAPI를 통한 웹 API활용법에 대해 공부해보았다.
구글 플레이스토어에 수많은 앱이 있는데 이러한 앱의 댓글들을 크롤링을 통해서 수집하여, 데이터를 저장하는 코드를 만들어보았다.
from selenium import webdriver
from selenium.webdriver.common.by import By
from datetime import datetime
# (1) 링크 생성
keyword = input("수집하고자 하는 앱 이름을 입력하세요 : ")
url = f'https://play.google.com/store/search?q={keyword}&c=apps'
print(url)
# (2) 브라우저를 열고, 페이지 이동
browser = webdriver.Chrome()
browser.get(url)
# (3) 앱의 상세 페이지로 이동
app_url = browser.find_element(By.CLASS_NAME, 'Qfxief').get_attribute('href')
browser.get(app_url)

# (4) 리뷰 더 보기 클릭
browser.find_element(By.XPATH, '//*[@id="yDmH0d"]/c-wiz[2]/div/div/div[1]/div/div[2]/div/div[1]/div[1]/c-wiz[5]/section/div/div[2]/div[5]/div/div/button/span').click()
# (5) 리뷰 스크롤 => JS // 검색 => 적용
# 모달창을 클릭한다.
browser.find_element(By.CLASS_NAME, 'fysCi').click()
# javascript코드를 통해서 스크롤을 내려준다. (네이버 로그인)
modal_elem = browser.find_element(By.CLASS_NAME, 'fysCi')
import time
for i in range(5):
js_code = 'arguments[0].scrollTo(0, arguments[0].scrollHeight)'
browser.execute_script(js_code, modal_elem)
time.sleep(1)
datas = browser.find_elements(By.CLASS_NAME, 'RHo1pe')
data_list = []
for data in datas:
username = data.find_element(By.CLASS_NAME,'X5PpBb').text
content = data.find_element(By.CLASS_NAME,'h3YV2d').text
rank = data.find_element(By.CLASS_NAME,'iXRFPc').get_attribute('aria-label')[10:11]
pre_review_date = data.find_element(By.CLASS_NAME, 'bp9Aid').text
pre_review_date = pre_review_date.replace("년", "-").replace("월", "-").replace("일", "").replace(" ", "")
review_date = datetime.strptime(pre_review_date, "%Y-%m-%d").date()
data_list.append({
'유저명' : username,
'별표' : rank,
'작성일' : review_date,
'작성내용': content
})
import pandas as pd
df = pd.DataFrame(data_list)
df.to_csv('naver_playstore.csv',encoding='utf-8-sig',index=False)

이렇게 저장한 데이터에 자연어처리를 하면 워드클라우드 형태로 댓글 확인도 가능하고, 감성분석이나 키워드 분석등의 자연어 처리기술과 결합하면 다양한 분석을 할 수 있을것으로 생각되었다.
FastAPI 와 Tensorflow의 mobileNet V2 모델을 활용해서
웹페이지에 이미지를 업로드하면 바로 모델을 사용해볼 수 있도록 데모페이지를 제작해 보았다.
기본적으로 FastAPI 웹페이지를 호스팅할 main.py가 필요하다.
# 필요한 라이브러리와 모듈을 임포트합니다.
from fastapi import FastAPI, File, UploadFile # FastAPI와 파일 업로드를 위한 클래스를 임포트합니다.
from PIL import Image # 이미지 처리를 위해 PIL 라이브러리의 Image 모듈을 임포트합니다.
from io import BytesIO # 바이트 스트림을 다루기 위해 BytesIO를 임포트합니다.
from predict import predict # 예측 함수를 포함하고 있는 사용자 정의 모듈을 임포트합니다.
# FastAPI 애플리케이션 인스턴스를 생성합니다.
app = FastAPI()
# "/predict/image" 경로에 POST 요청이 들어왔을 때 실행할 함수를 데코레이터로 등록합니다.
@app.post("/predict/image")
async def predict_api(file: UploadFile = File(...)): # 비동기 함수로, 파일을 업로드 파일로 받습니다.
# 업로드된 파일의 확장자를 확인하여 jpg, jpeg, png인지 검사합니다.
extension = file.filename.split(".")[-1] in ("jpg", "jpeg", "png")
if not extension: # 확장자가 이들 중 하나가 아니라면 에러 메시지를 반환합니다.
return "Image must be jpg or png format!"
# 업로드된 파일을 PIL 이미지로 변환합니다. 이를 위해 파일을 바이트로 읽고, BytesIO로 이미지 데이터를 메모리에 로드합니다.
image = Image.open(BytesIO(await file.read()))
# 사용자 정의 `predict` 함수를 사용하여 이미지에 대한 예측을 수행합니다.
prediction = predict(image)
# 예측 결과를 반환합니다.
return prediction
# 스크립트가 직접 실행될 때만 아래 코드가 실행됩니다.
if __name__ == "__main__":
import uvicorn # ASGI 서버인 uvicorn을 임포트합니다.
# uvicorn을 사용하여 앱을 호스트합니다. 여기서 "main:app"는 이 스크립트(main.py)에 정의된 app 인스턴스를 가리킵니다.
uvicorn.run("main:app", port=8000, log_level="info")
# 필요한 라이브러리를 임포트합니다.
from PIL import Image # 이미지 처리를 위한 PIL 라이브러리
import numpy as np # 수치 연산을 위한 NumPy 라이브러리
from tensorflow.keras.applications.imagenet_utils import decode_predictions # 예측 결과를 해석하기 위한 함수
from model_loader import model # 사용자 정의 모듈에서 학습된 모델을 임포트합니다.
# 이미지를 입력받아 예측 결과를 반환하는 함수를 정의합니다.
def predict(image: Image):
# 입력 이미지를 224x224 크기로 조정하고, RGB 채널만 유지하며 NumPy 배열로 변환합니다.
image = np.asarray(image.resize((224, 224)))[..., :3] # RGB
# 변환된 이미지 배열에 배치 차원을 추가합니다. 이는 모델이 배치 처리를 기대하기 때문입니다.
image = np.expand_dims(image, 0)
# 이미지 데이터를 -1에서 1 사이의 값으로 정규화합니다. 이는 많은 사전 훈련된 모델의 입력 요구사항입니다.
image = image / 127.5 - 1.0 # Scaler(정규화)
# 로드된 모델을 사용하여 이미지에 대한 예측을 수행하고, 상위 3개의 예측 결과를 디코드합니다.
result = decode_predictions(model.predict(image), 3)[0] # 상위 3개의 결과 반환
# 예측 결과를 저장할 리스트를 초기화합니다.
result_list = []
# 예측 결과를 순회하며 각 클래스의 이름과 신뢰도를 결과 리스트에 추가합니다.
for res in result:
print(res) # 콘솔에 결과를 출력합니다.
# 결과 리스트에 클래스 이름과 신뢰도(확률)를 사전 형태로 추가합니다. 신뢰도는 백분율로 변환됩니다.
result_list.append({"class": res[1], "confidence": f"{res[2]*100:0.2f} %"})
# 최종적으로 구성된 결과 리스트를 반환합니다.
return result_list
# TensorFlow 라이브러리를 tf라는 별칭으로 임포트합니다.
import tensorflow as tf
# 사전 훈련된 모델을 로드하는 함수를 정의합니다.
def load_model():
# tf.keras.applications에서 제공하는 MobileNetV2 모델을 로드합니다.
# weights='imagenet'은 ImageNet 데이터셋으로 사전 훈련된 가중치를 사용하겠다는 의미입니다.
model = tf.keras.applications.MobileNetV2(weights="imagenet")
# 모델이 성공적으로 로드되었음을 콘솔에 출력합니다.
print("Model loaded")
# 로드된 모델을 반환합니다.
return model
# load_model 함수를 호출하여 모델을 로드하고, 이를 model 변수에 할당합니다.
model = load_model()
Using Page
요크셔테리어 이미지를 모델에 넣어서 확인해보자.
강아지 이미지를 웹페이지에 업로드하여 execute 해보면 결과를 얻을 수 있다.

[
{
"class": "Yorkshire_terrier",
"confidence": "95.57 %"
},
{
"class": "Australian_terrier",
"confidence": "0.63 %"
},
{
"class": "Norfolk_terrier",
"confidence": "0.59 %"
}
]
Yorkshire_terrier가 95.57%로 모델이 잘 작동해서 결과를 보여주는걸 확인할 수 있었다.
파이썬으로 데이터분석이나 간단한 데모페이지를 한 경험이 있어서 약간씩은 아는 분야라 재미있게 잘 했던 것 같다.
다만 프로젝트에 실제로 적용해보기 위해서는 FastAPI든 Selenium이든 추가적인 공부와 구글링이 필수적일 것으로 생각이 된다.
할수록 성장하는 느낌이 뿌듯하고 좋은것같다.