본문 바로가기
IT & 데이터 사이언스/개인 프로젝트

[프로젝트] RPA로 MBTI_16Personality 경우의 수 확인하기(2)

by 바른 호랑이 2022. 5. 20.
728x90
반응형

※ 심심해서 해보는 RPA관련 Toy_Project

  지난 게시글에서는 Python과 VSCode, Selenium을 활용하여 16Personality 페이지의 결과를 RPA를 해보았습니다. 이번 게시글에서는 결과를 Crawling해서 csv 파일화 하는 과정을 진행하는 것에 대해 설명해보려고 합니다. 우선 Python 환경에서 Crawling을 해서 데이터 프레임으로 변환 후 csv 파일 변환을 하기 위해서는 2가지가 더 필요합니다. Pandas와 BeautifulSoup 라이브러리가 필요한데 2가지 모두 cmd와 pip를 활용하여 설치가 가능하니 설치를 완료했다는 가정하에 해당 내용들을 보면 되겠습니다. 기본적인 로직은 Selenium을 활용한 RPA를 진행한 후 마지막에 출력되는 결과 페이지의 html코드에서 BeautifulSoup를 활용하여 결과값을 뽑아낸 후 그 값들을 Pandas DataFrame 형태로 변환하여 csv파일로 저장하는 것으로 이해하시면 되겠으며, 그 이외의 것들은 크게 설명할 것이 없어 코드에 추가한 주석들을 참고해주시기 바랍니다.

Crawling할 HTML 코드

# 필요 패키지 로드
# RPA
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
# Crawling
import pandas as pd
import requests
from tqdm.notebook import tqdm
from bs4 import BeautifulSoup
from tqdm.notebook import tqdm # 반복문 실행시 실행도 확인용 라이브러리

# 모든 경우의 수 산출은 성능문제로 불가 - 30개를 난수로 추출하여 30개만 확인
# 추출용 사용자 정의 랜덤 함수 작성
def random_choice(number_of_cases, cases_origin):
    test_cases = []
    while len(test_cases) < number_of_cases:
        tn = random.randrange(len(cases_origin))
        if tn not in test_cases:
            test_cases.append(tn)
        else:
            pass
    return test_cases


# 선택가능한 모든 경우의 수 산출
# dfs 함수 또는 파이썬 라이브러리 이용 가능 / 메모리 문제로 구현 불가
from itertools import permutations # 일반 순열
from itertools import product # 중복을 허용하는 순열
import random

# 용량 문제로 중위 선택지는 제외 - 3, 4, 5번은 선택안하는 거로 변경 
# 홈페이지 문항선택시 추천사항 : 중위 수 선택 미추천
# 경우의 수 문제로 4개 선택지를 중복허용하여 6번씩 뽑아 만든 순열을 이어붙인형태로만 테스트(메모리 문제)
# 페이지당 문항수 6개 x 페이지 수 10개 = 60
cases = list(product([1, 2, 6, 7], repeat = 6))
print(len(cases))
for i in tqdm(range(len(cases))):
    cases[i] = list(cases[i])
    for _ in range(10):
        cases[i].extend(cases[i])
print(len(cases))
test_cases = [cases[i] for i in random_choice(30, cases)]
memo = pd.DataFrame({'index' : [i for i in range(len(test_cases))], 
					 'Case' : [cases[random.randrange(len(cases))] for i in range(30)], 
                     'MBTI_Type' : [0 for _ in range(len(test_cases))], 
                     '마음' : [0 for _ in range(len(test_cases))], 
                     '에너지' : [0 for _ in range(len(test_cases))],
                     '본성' : [0 for _ in range(len(test_cases))], 
                     '자아' : [0 for _ in range(len(test_cases))]})
# 초기파일 생성
memo.to_csv('C:\\Workspace\\python\\Toy_Project_2022\\data\\case.csv', sep=',', index = False)


URL = "https://www.16personalities.com/ko"
# test_cases = [[1 for i in range(60)], [1 for i in range(30)] + [7 for i in range(30)]]

for i in tqdm(range(len(test_cases))):
# for i in tqdm(range(2)):    
    # 문항 체크 경우의 수 선언
    present_case = memo.Case[i]

    # Selenium 실행 후 16personality 사이트 접속
    driver = webdriver.Chrome('C:\\Workspace\\python\\Toy_Project_2022\\chrome\\chromedriver.exe')
    driver.get(URL)
    time.sleep(2) # 로딩시간에 맞게 적정히 수정
    driver.find_element(By.XPATH, '//*[@id="main-app"]/main/div[1]/div[2]/a').click()
    time.sleep(2) # 로딩시간에 맞게 적정히 수정

    # 문항에 체크할 번호 초기화
    cp = 0    
    ## 모든 응답문항 체크 홈페이지 구조 동일(페이지당 문항 6개) // 총 10개 페이지
    for _ in range(10):
        driver.find_element(By.XPATH, '//*[@id="main-app"]/div[1]/div/div[2]/div[1]/div[2]/div[2]/div[' + str(present_case[cp]) + ']').click()
        time.sleep(1) # 로딩시간에 맞게 적정히 수정
        driver.find_element(By.XPATH, '//*[@id="main-app"]/div[1]/div/div[2]/div[2]/div[2]/div[2]/div[' + str(present_case[cp+1]) + ']').click()
        time.sleep(1) # 로딩시간에 맞게 적정히 수정
        driver.find_element(By.XPATH, '//*[@id="main-app"]/div[1]/div/div[2]/div[3]/div[2]/div[2]/div[' + str(present_case[cp+2]) + ']').click()
        time.sleep(1) # 로딩시간에 맞게 적정히 수정
        driver.find_element(By.XPATH, '//*[@id="main-app"]/div[1]/div/div[2]/div[4]/div[2]/div[2]/div[' + str(present_case[cp+3]) + ']').click()
        time.sleep(1) # 로딩시간에 맞게 적정히 수정
        driver.find_element(By.XPATH, '//*[@id="main-app"]/div[1]/div/div[2]/div[5]/div[2]/div[2]/div[' + str(present_case[cp+4]) + ']').click()
        time.sleep(1) # 로딩시간에 맞게 적정히 수정
        driver.find_element(By.XPATH, '//*[@id="main-app"]/div[1]/div/div[2]/div[6]/div[2]/div[2]/div[' + str(present_case[cp+5]) + ']').click()
        time.sleep(1) # 로딩시간에 맞게 적정히 수정
        driver.find_element(By.XPATH, '//*[@id="main-app"]/div[1]/div/div[3]/button').click()
        time.sleep(2) # 로딩시간에 맞게 적정히 수정
        cp += 6

    Mbti_Type = driver.find_element(By.XPATH, f'//*[@id="main-app"]/main/section/div[1]/div[3]').text
    raw = driver.find_element(By.XPATH, f'//*[@id="main-app"]/main/section/div[2]').text.split('\n')
    # 각 수치별 카테고리 일치화 / 대분류 : 0 - 마음, 5 - 에너지 / 10 - 본성 / 15 - 전술 / 20 - 자아
    # 3, 1 / 4, 2 / 8, 6 / 9, 7 / 11, 8 / 12, 9 / 18, 16 / 19, 17 / 23, 21 / 24, 22
    changed = [
                [raw[0], [[raw[3], raw[1]], [raw[4], raw[2]]]], # 마음
                [raw[5], [[raw[8], raw[6]], [raw[9], raw[7]]]], # 에너지
                [raw[10], [[raw[11], raw[8]], [raw[12], raw[9]]]], # 본성
                [raw[15], [[raw[18], raw[16]], [raw[19], raw[17]]]], # 본성
                [raw[20], [[raw[23], raw[21]], [raw[24], raw[22]]]] # 자아
            ]
    memo['MBTI_Type'][i] = Mbti_Type
    for k in range(len(changed)):
        for column in memo.columns[3:]:
            if changed[k][0] == column:
                memo[column][i] = changed[k][1]
    time.sleep(2) # 로딩시간에 맞게 적정히 수정
    driver.close()
    
    
# 로직 완료 후 결과 확인
memo.to_csv('C:\\Workspace\\python\\Toy_Project_2022\\data\\case_30.csv', index = False)
pd.read_csv('C:\\Workspace\\python\\Toy_Project_2022\\data\\case_30.csv', sep=',')

 

P.S 더 나은 개발자가 되기위해 공부중입니다. 잘못된 부분을 댓글로 남겨주시면 학습하는데 큰 도움이 될 거 같습니다.

세부코드가 궁금하신 분들은 아래 GitHub를 참고해주시기 바랍니다.

 

※ Github 

 

GitHub - Jeong-Beom/Toy_Project_2022: 2022년도에 진행한 Toy_Project들에 대한 레파지토리입니다.

2022년도에 진행한 Toy_Project들에 대한 레파지토리입니다. Contribute to Jeong-Beom/Toy_Project_2022 development by creating an account on GitHub.

github.com

※ [MBTI_16Personality] RPA로 경우의 수 확인하기(1)

 

[MBTI_16Personality] RPA로 경우의 수 확인하기(1)

※ 심심해서 해보는 RPA관련 Toy_Project 최근들어 인간의 성격유형을 정리해놓은 MBTI에 관심이 생겨 관련 성격유형들에 대한 내용들을 읽다가 테스트 문항들의 조합에 따른 MBTI 결과가 어떻게 나오

data-is-power.tistory.com

 

728x90
반응형

댓글