본문 바로가기
FastCampus X Upstage AI 부트캠프/과제 및 일반글

FastCampusxUpstage seleniumxfastapi

by tankwoong 2024. 4. 9.
반응형

selenium으로 구글 스토어 앱 csv파일 만들기

필요한 라이브러리 설치를 설치한다.

!pip install selenium
!pip install webdriver-manager

필요한 패키지 임포트 및 설치한다.

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
ChromeDriverManager().install()
browser = webdriver.Chrome()

검색하려는 앱을 선택해서 댓글 창까지 이동한다.

keyword =  input('검색하고자하는 앱이름을 입력하세요.')
url = f'https://play.google.com/store/search?q=c={keyword}&apps&hl=ko-KR'
print(url)
browser = webdriver.Chrome()
browser.get(url)
app_url = browser.find_element(By.CLASS_NAME, 'Si6A0c').get_attribute('href')
browser.get(app_url)
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/header/div/div[2]/button').click()
browser.find_element(By.CLASS_NAME, 'fysCi').click()

검색에서 앱이름을 입력받아 헤더를 클릭해서 스크롤이 가능하게 한다.

modal_elem = browser.find_element(By.CLASS_NAME, 'fysCi')
import time
for i in range(6):
    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
    rank = data.find_element(By.CLASS_NAME, 'iXRFPc').get_attribute('aria-label').split()[1]
    date = data.find_element(By.CLASS_NAME, 'bp9Aid').text
    content = data.find_element(By.CLASS_NAME, 'h3YV2d').text
    
    data_list.append({
        '유저명': username,
        '별표': rank,
        '작성일': date,
        '작성내용': content
    })

이후 필요한 유저명, 별표, 작성일, 작성 내용을 기준으로 data_list을 작성한다.

import pandas as pd

df = pd.DataFrame(data_list) # 백엔드<->머신러닝 엔지니어<->데이터엔지니어
df.to_csv("google_playstore.csv", encoding='utf-8-sig')

판다스를 불러오고, csv파일을 만들어준다.

성공적으로 csv파일이 만들어진 것을 확인할 수 있다.

fastapi실습 1 -이미지 올리고 분류하기 

#main.py#

from fastapi import FastAPI,UploadFile, File 
from PIL import Image
from io import BytesIO


app = FastAPI()

@app.get("/")
def index():
    return {"Hello":"World!"}
from predict import predict
@app.post("/predict/image")
async def predict_api(file: UploadFile = File(...)):
    extension = file.filename.split(".")[-1] in ("jpg", "jpeg", "png")
    if not extension:
        return "Image must be jpg or png format!"
    image = Image.open(BytesIO(await file.read()))
    prediction = predict(image)
    return prediction

if __name__ == "__main__": # python main.py
    import uvicorn
    uvicorn.run("main:app", reload=True)

jpg파일을 가져와서 인공지능의 분류를 하는 모델의 main을 작성해 주었다.

#model_loader.py#

import tensorflow as tf

def load_model():
    model = tf.keras.applications.MobileNetV2(weights="imagenet")
    print("Model loaded")
    return model

model = load_model()

텐서플로우를 기반으로 한 imagenet에서 모델을 만들어준다.

#predict.py

from PIL.Image import Image
import numpy as np
from tensorflow.keras.applications.imagenet_utils import decode_predictions
from model_loader import model


# 이미지를 예측해서 결과를 알려주는 함수
def predict(image: Image):
    image = np.asarray(image.resize((224, 224)))[..., :3] # RGB
    image = np.expand_dims(image, 0)
    image = image / 127.5 - 1.0 # -1~1사이의 숫자로 바뀌는데 -> Scaler(정규화)
    result = decode_predictions(model.predict(image), 3)[0] # 2: 상위 2개의 결과 반환

    result_list = []
    for res in result:
        print(res)
        result_list.append({"class": res[1], "confidence": f"{res[2]*100:0.2f} %"})

    return result_list

예측모델은 이미지의 모양과 정규화를 진행해 준다.

eagle을 올렸을 때 3가지를 잘 분류해 주는 것을 알 수 있다.

fastapi실습 2 - 책 메모리를 CRUD 하기 

#book.py#
# 책 데이터를 CRUD하는 REST API를 만들어 보겠습니다.
from fastapi import APIRouter

# 메모리 DB
BOOKS = [
    {
        'id': 1,
        'title': '변하지 않는 원칙',
        'author': '모건 하우절',
        'url': 'http://yes24.com/변하지않는원칙'
    }
]

# router => url을 맵핑시켜주는 역활
router = APIRouter(prefix='/api/v1/books', tags=["books"])

# api/v1/books [GET]
@router.get('/') # read
def get_all_books():
    return BOOKS

# api/v1/books/{book_id}
# api/v1/books/1 [GET]
@router.get('/{book_id}')
def get_book(book_id: int):
    # next() => 파이썬 내장함수
    book = next((book for book in BOOKS if book['id'] == book_id), None)
    # for book in BOOKS:
    #     if book['id'] == book_id:
    #         book
    #         break

    if book:
        return book
    return {"error":f"Book not found ID: {book_id}"}

# api/v1/books [POST] => REST API
@router.post('/')
def create_book(book: dict): # {'id':2, 'title':''}
    BOOKS.append(book)
    return book

# api/v1/books/{book_id}
@router.put('/{book_id}')
def update_book(book_id: int, book_update: dict):
    book = next((book for book in BOOKS if book['id'] == book_id), None)

    for key, value in book_update.items():
        if key in book:
            book[key] = value

    return book
    
# api/v1/books/{book_id}
@router.delete('/{book_id}')
def delete_book(book_id: int):
    global BOOKS

    BOOKS = [item for item in BOOKS if item['id'] != book_id]

    return {'message': f'Success to delete book ID: {book_id}'}
from fastapi import FastAPI,UploadFile, File 
from PIL import Image
from io import BytesIO
from book import router as book_router


app = FastAPI()
app.include_router(book_router) 

if __name__ == "__main__": # python main.py
    import uvicorn
    uvicorn.run("main:app", reload=True)

book.py에 crud세팅을 해주고, main 파이썬을 구동해 준다.

get에서는 그대로 받아온다.

post를 작성하면 get에 저장되어 읽을 수 있다.

put을 통해서는 업데이트를 할 수 있다.

업데이트된 것을 확인할 수 있다.

2번을 지워보겠다.

 

셀레늄이랑 fastapi를 사용해서 크롤링과 백엔드 신을 이해해 보았다. 아직 프로젝트 한 번도 안 해본 나에게는 굉장히 벅차고, 어려웠다. 잘할 수 있을지 확신이 들지는 않지만 버텨봐야겠다.

 

반응형