ChatGPT 백준 매크로 만들기

terlinko·2023년 3월 22일
0
post-thumbnail

ChatGPT API 와 Python 의 Selenium 을 이용해서 ChatGPT 를 백준 풀이 노예로 만들어보자.

ChatGPT API 안 써보면 뒤쳐지는 느낌이라 써볼만한 걸 생각해봤는데 내 뇌는 이게 한계였다.

목표는 백준 한 페이지, 총 100문제 ChatGPT가 풀고 Selenium이 제출.

1. 대답 노예 생성

import openai
openai.api_key = "#####"
my_model = "gpt-3.5-turbo"

GPT-4가 나왔는데 드디어 3.5 터보를 써본다.

사실 ChatGPT API 사용에 큰 의의는 없다.
다들 챗지피티지피티하는데 내 과제 노예로 쓸 수 있을까 테스트 해보자.

my_messages = [
	"role": "system", "content" : "You will send me python code that can solve the problem in BOJ"},
]

역할을 너무 길게 줬나 하는 생각도 들지만, 여러번의 시행 착오 끝에 정확하게 명시하는게 더 나은 결과가 나오는 것 같아서 아는 영단어 총동원해서 작성해줬다.

대답 노예에게 줄 두가지 선택지를 생각해봤다.

1. 문제 내용 줘, 내가 알고리즘 짜볼게
2. 주인님. 문제 번호만 주시면 알아서 해보겠습니다

재수가 없으니까 두번째로 간다.

ChatGPT API 사용은 다음과 같다.

chat = openai.ChatCompletion.create(
	model = my_model, messages = my_messages
)

아무리 생각해도 model 을 먼저 create 해둔 다음에, 메시지 송신하는게 맞는 것 같은데..
구글링 실력이 미흡해서 이 방법밖에 모르겠다.

{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "왈왈",
        "role": "assistant"
      }
    }
  ],
  "created": ######,
  "id": "#######",
  "model": "gpt-3.5-turbo-0301",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 10,
    "prompt_tokens": 18,
    "total_tokens": 28
  }
}

그럼 chat 은 다음과 같이 구성된다.
"role""system"이라고 명시했는데 왜 "assistant"가 된지는?
몰라.
내가 필요한건 대답

reply = chat['choices'][0]['message']['content']

웃긴 건 다시 질문하면 얘가 대답했던 걸 기억 못하는지.
얘가 했던 대답도 넣어서 질문해야한다.

ChatGPT에게 문제 번호를 주고 풀어보라 하면 문제 설명을 열심히 한 뒤에 코드를 던져준다.

문제 설명 어쩌고 저쪼고 나 이렇게 풀었음ㅋ
```python
print("응애 나 CGPT")
```ㅤ
꼭 한마디씩 더해버리기~

코드를 제출하기 위해 가공해보자.

code_start = reply.find('```python')+10
temp = reply[code_start:]
code_end = temp.find('```')-1
reply = temp[:code_end]

아무튼 ChatGPT는 이쯤하고

2. Selenium 으로 백준 뒤지기

원래는 requests, beautifulsoup 을 사용해서 백준을 볶아 먹으려 했는데
reCAPTCHA 인가 머시기 때문에 로그인부터 실패한다.
그래서 뤼캡초ㅑ 의 하드 카운터인 쇌래늄으로 볶았다.
Selenium 으로 로그인, requests 에 로그인 세션 보내기 방법도 해봤는데, 안된다.

뭐 아무튼.
사실 Selenium, requests, beautifulsoup 다 처음 써봐서 ChatGPT 보다 시간을 더 잡아먹었다.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome("본인 크롬드라이버 주소")
driver.get("https://www.acmicpc.net")

그럼 크롬이 열리고 백준에 접근이 된다.
나중에 안건데 그 상태에서 로그인을 수동으로 하면 시행착오 없이 넘어갈 수 있었다.

근데 난 몰랐지

driver.find_element(By.LINK_TEXT, '로그인').click()

사실 이런식으로 하는 것 보다는 처음부터 https://www.acmicpc.net/login 으로 접속하는게 더 좋을 듯 하다.
근데 멋있잖아.

find_elementBy.NAME , By.ID , send_keys 등을 이용하면 로그인에 성공한다.

로그인에 성공했으면 https://www.acmicpc.net/problem/unsolved 에 접속했을 때 의미있는 결과가 나온다.
이 정보들을 beautifulsoup로 문제 번호만 빼올 것이다.

import bs4 import BeautifulSoup as bs
driver.get("https://www.acmicpc.net/problem/unsolved")
html = driver.page_source
soup = bs(html, 'html.parser')
problems = soup.findAll(class_='list_problem_id')

자 이제, problems 안에는 내가 안 푼 문제 100 개의 번호가 들어있다.
webdriver 은 백준에 로그인이 되어있다.

더 할 게 없네? 끝.

이라 생각했다.

https://www.acmicpc.net/submit/문제번호 에 접속해보면 어떤 elementsend_keys 를 해야할 지 감이 안 온다.

textarea 를 찾긴 찾았는데 뭐 상호 작용이 안 된다나 뭐라나
다른 방법이 있을 수 있겠지만, 한 30분동안 webdriver 에서 계속 튕기기만 하니 정신이 나갈 것 같았다.
get 으로 접속하면 커서가 깜빡이는 것에 집중해보자.
그럼 붙여넣기가 가능...

2-2. pyperclip

import pyperclip

이 귀여운 녀석. pyperclip.copy("문자열 ><") 한 줄이면 내 클립보드에 문자열을 박아준다.
내 노예가 일하는 동안에 내가 클립보드에 이상한 걸 때려박지 않는다면, 붙여넣기로 코드 전송이 가능하다.

2-3. ActionChains

from selenium.webdriver.common.action_chains import ActionChains

어떻게 붙여넣기 하지?
ActionChains 를 이용하면 된다.

ActionChains(driver).key_down(Keys.COMMAND).send_keys('v').key_up(Keys.COMMAND).perform()

좀 길지만. 한줄이면 webdriver에 붙여넣기 할 수 있다.

이제 제출 버튼만 find_element로 찾아서 클릭하면 된다.

3. 가보자

이제 해보자고.
내 노예가 일하는 순서는 다음과 같다.

1. 백준에 로그인할게요
2. 안 푼 문제 100개 받아올게요
---반복문 입장---
3. 지피티야 이거 좀 풀어봐
4. 대답 가공해서 복붙
5. 제출 !

새로운 아이디를 만들었다. 헬로월드부터 시작이다.
문제가 엄청 쉬운 문제들인데 푸는 시간이 되게 들쑥날쑥이다.
그러다 알 수 없는 오류로 꺼졌고 24문제 풀었다.
컴파일 에러pyperclip 쓰기 전 send_keys 로 보내다가 띄어쓰기 중첩으로 에러가 났다. c나 c++ 이였으면 상관없었을텐데 파이썬.. 이래서 싫다.
런타임 에러도 한번 나왔는데 코드길이가 1B 였다. 한글자만 뱉은 대답 노예

수정하다가 한번 틀렸지만 코드 문제는 아니라 맞았다치자.
GPT가 뱉어낸 답은 틀린 게 없다. 복붙하는 과정에서 상품이 좀 상했을뿐.
백준 제일 쉬운 24문제에서 틀려버리면 그것도 문제긴 하다.

아마 중간에 튕긴 이유는 chatGPT 토큰 문제일 가능성이 크다.
24문제로 만족하자

목표 달성은 실패했지만 더이상 ChatGPT가 푸는 걸 기다려줄 인내심이 없다.
Selenium, requests, bs4 시행착오로 얻을 걸 얻었다 자기 위로 하고 마무리.

0개의 댓글