파이썬이 제일 쉬워

[Python] Selenium 실습, ClassCard 매칭 게임 자동화하기 #1 [Outdated] 본문

Python

[Python] Selenium 실습, ClassCard 매칭 게임 자동화하기 #1 [Outdated]

HighBright 2022. 3. 13. 20:59

 

Selenium 실습, ClassCard 매칭 게임 자동화하기 #1
 

 

현 게시글의 방법은 더이상 사용하실 수 없습니다.

아래 글로 이동해주시기 바랍니다!

2024.06.18 - [Python] - [Python/Selenium] ClassCard 리벤지, 테스트/매칭게임 자동화


공교육, 사교육에서 가리지 않고 자주 사용하는 온라인 영어 단어장 ClassCard에는 매칭 게임이라는 것이 있다.

위와 같은 식으로 영어 단어와 알맞은 뜻을 연결해 선택하는 영어 학습 게임이다.
이번에는 위 게임을 자동화하는 프로그램을 짜 보도록 하겠다.
 
일단 openpyxl을 이용해 영어 단어와 뜻을 dict 타입으로 만들어보자.
클래스 카드 사이트에서 정보를 가져오고
 

이를 엑셀에 넣어준다, 물론 다른 방식으로 dict를 만들어도 된다.

import openpyxl

wb = openpyxl.load_workbook('list.xlsx')
engdict = {}
for i in range(1, 단어 개수):
    engdict[sheet.cell(row=i, column=1).value] = sheet.cell(row=i, column=2).value

다음으로는 Selenium을 사용하기 위해서 기본 틀을 만들자.
크롬 드라이버는 여기서 다운로드할 수 있다.

from selenium import webdriver

url = "https://www.classcard.net/Match/8259894?c=0&s=1"
driver = webdriver.Chrome("./chromedriver.exe")
driver.get(url)

input("대기")

이렇게 만들어주고, 게임 내의 요소를 분석해보자, 위의 그림을 보면 좌측에 카드 4개, 우측에 카드 4개가 있다.
크롬 개발자 도구로 이들의 XPATH를 구하고 밑과 같게 설정해준다.

        lc1 = driver.find_element(By.XPATH, value='//*[@id="left_card_0"]/div/div[1]/div/div')
        lc2 = driver.find_element(By.XPATH, value='//*[@id="left_card_1"]/div/div[1]/div/div')
        lc3 = driver.find_element(By.XPATH, value='//*[@id="left_card_2"]/div/div[1]/div/div')
        lc4 = driver.find_element(By.XPATH, value='//*[@id="left_card_3"]/div/div[1]/div/div')

        rc1 = driver.find_element(By.XPATH, value='//*[@id="right_card_0"]/div/div/div/div')
        rc2 = driver.find_element(By.XPATH, value='//*[@id="right_card_1"]/div/div/div/div')
        rc3 = driver.find_element(By.XPATH, value='//*[@id="right_card_2"]/div/div/div/div')
        rc4 = driver.find_element(By.XPATH, value='//*[@id="right_card_3"]/div/div/div/div')

이제 왼쪽 카드(lc*)에서 영어를 긁어와서 dict에 대입해 뜻을 가져오고 오른쪽 카드(rc*)의 내용과 같으면
두 카드를 클릭하도록 만든다.

for lc in [lc1, lc2, lc3, lc4]:
	for rc in [rc1, rc2, rc3, rc4]:
		if rc.text in engdict[lct]:
			lc.click()
			rc.click()
			time.sleep(1.5)

 
몇 가지 예외처리 코드를 만들고 완성한다.
 
전체 코드 : 

import selenium.common.exceptions
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import openpyxl

wb = openpyxl.load_workbook('list.xlsx')
sheet = wb.get_sheet_by_name('시트1')
engdict = {}

for i in range(1, 400):
    engdict[sheet.cell(row=i, column=1).value] = sheet.cell(row=i, column=2).value

driver = webdriver.Chrome("./chromedriver.exe")
url = "https://www.classcard.net/Match/8259894?c=0&s=1" #본인의 링크로 바꾸세요.
driver.get(url)

input("시작하시려면 엔터를 눌러주세요")

while True:
    try:
        lc1 = driver.find_element(By.XPATH, value='//*[@id="left_card_0"]/div/div[1]/div/div')
        lc2 = driver.find_element(By.XPATH, value='//*[@id="left_card_1"]/div/div[1]/div/div')
        lc3 = driver.find_element(By.XPATH, value='//*[@id="left_card_2"]/div/div[1]/div/div')
        lc4 = driver.find_element(By.XPATH, value='//*[@id="left_card_3"]/div/div[1]/div/div')

        rc1 = driver.find_element(By.XPATH, value='//*[@id="right_card_0"]/div/div/div/div')
        rc2 = driver.find_element(By.XPATH, value='//*[@id="right_card_1"]/div/div/div/div')
        rc3 = driver.find_element(By.XPATH, value='//*[@id="right_card_2"]/div/div/div/div')
        rc4 = driver.find_element(By.XPATH, value='//*[@id="right_card_3"]/div/div/div/div')

        try:
            for lc in [lc1, lc2, lc3, lc4]:
                for rc in [rc1, rc2, rc3, rc4]:
                    if rc.text in engdict[lc.text]:
                        lc.click()
                        rc.click()
                        time.sleep(1.5)

        except KeyError:
            print("사전에 없는 단어")

    except selenium.common.exceptions.NoSuchElementException:
        print("해당하는 오브젝트를 찾을 수 없음")
    except selenium.common.exceptions.StaleElementReferenceException:
        print("너무 빠른 접근 시도")
    except selenium.common.exceptions.ElementNotInteractableException:
        print("요소에 접근 할 수 없음")
    #except:  
        #print("알 수 없는 오류")   실행에 지장없는 지속적인 오류 발생시 삽입

하지만, 1분 30초 이후에 영어 발음 카드가 나오는 경우가 있다.
이때는 위의 코드를 사용하면 에러가 발생하기 때문에 따로 코드를 만들어서 대응해야 한다.
영어 발음 카드 대응은 다음 편에 다루도록 하겠다.

Comments