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파일로 저장하는 것으로 이해하시면 되겠으며, 그 이외의 것들은 크게 설명할 것이 없어 코드에 추가한 주석들을 참고해주시기 바랍니다.
# 필요 패키지 로드
# 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
※ [MBTI_16Personality] RPA로 경우의 수 확인하기(1)
728x90
반응형
'IT & 데이터 사이언스 > 개인 프로젝트' 카테고리의 다른 글
[프로젝트] Django로 포트폴리오 사이트 만들기(3) - 운영 서버 환경 설정 및 사이트 배포하기 (0) | 2024.07.11 |
---|---|
[프로젝트] Django로 포트폴리오 사이트 만들기(2) - Django 프로젝트 생성 및 Bootstrap 적용하기 (2) | 2024.07.05 |
[프로젝트] Django로 포트폴리오 사이트 만들기(1) - Ubuntu Server 환경설정 및 가상환경 만들기 (0) | 2024.07.02 |
[프로젝트] RPA로 MBTI_16Personality 경우의 수 확인하기(1) (0) | 2022.05.15 |
댓글