백준 자동 제출 파이썬 스크립트

폭풍저그머성찡 ㅣ 2023. 3. 27. 17:46

곧 훈련소 들어가야하는데 백준 스트릭을 지키기 위해 만들었다. 

 

난 당연히 훈련소에서 훈련 일과 마치면 폰 할 수 있을 줄 알았는데 연대마다 다르다고 하더라..

 

내가 다 만든건 당연히 아니고 아래 링크 소스를 베이스로 안되는 것만 조금 고쳤다. 몇 년전 코드라 그런지 뭔가 달라져서 안되나보다.

 

https://github.com/blurfx/BOJ-AutoSubmit

 

GitHub - blurfx/BOJ-AutoSubmit: 백준 온라인 저지 자동 제출 툴

백준 온라인 저지 자동 제출 툴. Contribute to blurfx/BOJ-AutoSubmit development by creating an account on GitHub.

github.com

import sys
import time
import os
import schedule
from datetime import datetime

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

user_agent = 'Mozilla/5.0 CK={} (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko'
source_code_path = r".\source_code" # 제출 예정 소스코드 파일 저장 폴더
ac_path = r".\AC" # 맞은 소스 저장
wa_path = r".\WA" # 틀린 소스 저장

options = Options()
# options.add_argument('headless')  # 이거 주석풀면 테스트 브라우저 안뜸
options.add_argument("--window-size=1920,1080")
options.add_argument("user-agent=" + user_agent)
driver = webdriver.Chrome('chromedriver', options=options)


def login(id, password):
    driver.get('https://www.acmicpc.net/login?next=%2F')
    el_id = driver.find_element(By.NAME, 'login_user_id')
    el_pass = driver.find_element(By.NAME, 'login_password')
    bt_login = driver.find_element(By.ID, 'submit_button')
    el_id.send_keys(id)
    el_pass.send_keys(password)
    bt_login.click()
    time.sleep(10)
    return driver.find_element(By.CSS_SELECTOR, 'body > div.wrapper > div.header.no-print > div.topbar > div > ul > li:nth-child(1) > a').text


def submit(problem_id, language, source_code):
    driver.get('https://www.acmicpc.net/submit/{0}'.format(problem_id))

    WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.ID, 'language_chosen')))
    driver.execute_script('$("#language_chosen").trigger("mousedown");')

    langs = WebDriverWait(driver, 3).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.chosen-results li')))
    lang_selected = False

    for lang in langs:
        if lang.text.lower() == language.lower():
            lang_selected = True
            lang.click()
            break

    if not lang_selected:
        return False

    cm = driver.find_element(By.CLASS_NAME, 'CodeMirror')
    cl = cm.find_elements(By.CLASS_NAME, 'CodeMirror-line')[0]
    cl.click()
    txtbx = cm.find_element(By.CSS_SELECTOR, 'textarea')
    txtbx.send_keys(source_code)
    driver.find_element(By.ID, 'submit_button').click()
    while driver.find_element(By.CLASS_NAME, 'result').text.startswith('채점'):
        time.sleep(1)
    return driver.find_element(By.CLASS_NAME, 'result').text


def change_brackets(source_code): # 괄호 자동 완성 기능 때문에 이렇게 해야함
    source_code = str.replace(source_code, "(", "()\b")
    source_code = str.replace(source_code, "{", "{}\b")
    source_code = str.replace(source_code, "[", "[]\b")
    source_code = str.replace(source_code, "\"", "\"\"\b")
    source_code = str.replace(source_code, "\'", "\'\'\b")
    return source_code


print("login account : " + login('아이디', '비번'))
codelist = [os.path.join(source_code_path, file) for file in os.listdir(source_code_path) if file.endswith(".cpp") and os.path.isfile(os.path.join(source_code_path, file))]

# .\source_code 디렉터리 내의 모든 cpp 파일 제출 ( 문제 번호는 파일 이름 )
for codefile in codelist:
    print(codefile)
    code = open(codefile, "r").read()
    code = change_brackets(code)
    print(code)
    res = submit(os.path.splitext(os.path.basename(codefile))[0], 'C++17', code)
    print(os.path.splitext(os.path.basename(codefile))[0] + ' submit result : ' + res)

login('아이디', '비번') -> submit(문제번호, 제출 언어(제출 화면 콤보박스 항목 그대로 입력), change_brackets(제출소스코드))

 

하면 제출된다.

 

그리고 로그인 자주하면 그 사진 고르는거 떠서 로그인 안됨. 감지 주기가 어느 정돈지는 모르겠다.