1. WORDLE 이란
WORDLE 이라는 게임이 유행이다.
최근 미국 & 트위터를 중심으로 빠르게 퍼지고 있는 단순하고 쉬운 게임이다.
간단히 설명하면 다섯 글자로 이루어진 한 단어를 총 여섯번의 시도 내에 맞추면 되는 게임이다.
각 시도마다 힌트가 주어지는데, 녹색은 자리까지 정확한 글자,
노란색은 단어에는 있지만 자리가 틀린 글자,
회색은 단어에 없는 글자 이다.
해당 힌트를 가지고 다음 시도를 이어나가서 최종 단어를 맞추면 된다.
이 게임의 또 재밌는 점은 하루에 한 게임(한 단어)만 할 수 있고, 전 세계인이 같은 단어를 가지고 즐긴다는 점이다.
만약 연속해서 단어를 바꿔가며 계속 즐길 수 있으면, 하루에 몇시간 하고 그만둬버리는 게임이 될테지만,
하루에 한 게임만 할 수 있어서 매일 접속하게 된다. 단순한 기획으로 게임을 롱런할 수 있게 만드는 좋은 전략인 것 같다.
https://www.powerlanguage.co.uk/wordle/
한번 해보시라
2. 불편함에서 호기심으로
발명은 사소한 불편함을 해결하고자 하는 마음에서 시작된다.
게임을 하다보면 어휘력이 부족해서 힌트의 조합만으로 정답을 유추하기가 어려울 때가 있다. 몇 번의 시도를 하면서 완성되는 단어를 찾는다. 세번째 자리에 "A"는 들어가고, "T","H","R"...등등등은 포함되지 않고, 어느 위치인지 모르지만 "S"를 포함하는 단어가 무엇이 있더라.. 하면서 말이다.
그러다가 조건을 입력하면 조건을 만족하는 단어들을 한번에 보여주는 프로그램을 만들면 어떨까 생각이 들었다.
물론 게임을 클리어하는 재미 자체는 없어질지도 모른다.
그래도 자신들이 개발한 인공지능 바둑 프로그램이 인간을 이길 수 있는지 실험한 DeepMind의 마음과 같이,
내가 개발한 프로그램이 정확히 정답을 찾아가게 해줄 수 있는지, 내가 직접 단어를 조합하는 것보다 빠를 것인지 호기심이 생겼다.
한발 더 나아가서 머신러닝을 통해 프로그램이 직접 WORDLE 게임을 클리어하게 만들고, 그 성과가 인간보다 단연 앞서면 그것도 재밌겠다는 생각이 들었다. 물론, 이 부분은 추가로 공부할게 너무 많기 때문에 먼 미래의 프로젝트로 남겨둬야겠지만 말이다.
3. 프로젝트 구상
머릿속으로 프로젝트를 다음의 순서에 따라 간단히 구상해본다.
해당 프로그램을 만들려면 필요한 기능들을 정리한다.
이 중 내가 이미 해봤으며 구현할 수 있는 기능들을 체크한다.
그리고 내가 해보지 않았거나 미숙하지만, 쉽게 구현이 가능하다는 것을 알고 있고 이번 기회에 배울 수 있는 것들을 생각해본다.
구현가능성과 난이도가 가늠도 되지 않는 기능들이 있는지도 확인한다.
>필요한 기능들
-5글자로 이루어진 모든 영어단어를 크롤링해서 DB화
-쉽고 단순한 단어가 우선적으로 추출되도록 단어의 사용빈도를 수치화하는 방법
-사용자 입력 부분
-특정 알파벳이 몇번째 글자인지, 특정 알파벳이 제외되는지, 특정 알파벳이 포함되는지 입력되는 조건에 따른 단어들을 -추출
-배포를 위해 간단히 할 것
python으로 구현하면 대부분 비슷한 기능들을 다뤄봐서 쉽게 만들 수 있을 것 같았다. 그런데 다른 필요에 의해 C#을 공부하고 있으므로, C#으로 만들면 그 과정에서 C# 개발 연습이 많이 될 수 있을 것 같았다. 특히 C#으로 DB다루는 것은 어차피 익혀야할 일이다. 배포를 위해 DB는 간단한 sqlite3 를 쓰기로 했다.
사용빈도를 수치화하는 방법이 고민되긴 했는데, 엄청 디테일할 필요는 없다고 생각이 들었다. 단순하게 구글로 검색했을때 검색되는 페이지 수를 DB에 같이 넣고, 많이 검색되는 단어를 많이 쓰는 단어로 간주하기로 했다. 해보고 영 아니면 다시 고민해보기로 했다.
크롤링과 DB화 까지만 python으로 하고, 프로그램 구성은 C#으로 하기로 계획을 짰다.
4. 크롤링
5글자 단어를 전부 나열해주는 사이트를 찾는다.
구글에서 "5 letter words" 또는 "5 letter words with startting A" 등으로 검색해서 여러 페이지를 뒤진다.
중요한 것은 크롤링 하기 편해야 한다. 한 화면에 모든 단어를 보여주거나, 페이지 넘기는 부분을 HTML로 파싱하여 자동으로 조작할 수 있어야 한다. 여러 페이지를 뒤지다가 가능할 것 같은 페이지를 찾았다.
https://www.bestwordlist.com/d/a/1/5letterwordsbeginninga.htm
단어도 예쁘게 나열되어 있고, 무엇보다 어떤 글자로 시작하는지, 몇 페이지 인지가 url 주소에 전부 표시되는 사이트라서 접근이 간단했다.
변수에 알파벳을 입력하면 해당 알파벳으로 시작하는 5글자 단어를 크롤링해서 list로 돌려주는 함수를 만든다.
import requests
import selenium
from selenium import webdriver
from bs4 import BeautifulSoup
import sqlite3
import time
def wordsfind(letter):
webpage = requests.get(f"https://www.bestwordlist.com/d/{letter}/1/5letterwordsbeginning{letter}.htm")
soup = BeautifulSoup(webpage.content, "html.parser")
word_list = []
mot1 = soup.select(".mot")
mot2 = soup.select(".mot2")
for i in range(0, len(mot1)):
k = mot1[i].get_text().split(' ')
if '' in k:
k.remove('')
word_list.extend(k)
for i in range(0, len(mot2)):
k = mot2[i].get_text().split(' ')
if '' in k:
k.remove('')
word_list.extend(k)
f2list = soup.select(".f2")
if len(f2list) >= 8:
for i in range(7, len(f2list)):
webpage = requests.get(f"https://www.bestwordlist.com/d/{letter}/1/5letterwordsbeginning{letter}page{f2list[i].get_text()}.htm")
soup2 = BeautifulSoup(webpage.content, "html.parser")
mot1 = soup2.select(".mot")
mot2 = soup2.select(".mot2")
for i in range(0, len(mot1)):
k = mot1[i].get_text().split(' ')
if '' in k:
k.remove('')
word_list.extend(k)
for i in range(0, len(mot2)):
k = mot2[i].get_text().split(' ')
if '' in k:
k.remove('')
word_list.extend(k)
return word_list
그리고 해당 단어를 구글검색을 한 후, 검색결과수를 추출해서 DB에 함께 저장하는 부분을 만든다.
FIRMS 같은 어떤 단어는 검색하면 영화 목록 등 특정 컨텐츠가 바로 떠버려서 검색 결과 수가 나타나지 않기도 했다. 이런 단어들은 그래도 사용빈도가 아주 높은편이라고 봐야해서 그냥 10억값을 주기로 했다.
ALPHA = ['a', 'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
con = sqlite3.connect('words.db')
cur = con.cursor()
for V in ALPHA:
word_list = wordsfind(V)
options = webdriver.ChromeOptions()
options.add_argument('--lang=en')
driver = webdriver.Chrome('chromedriver.exe', chrome_options=options)
for i in range(0, len(word_list)):
url = f"https://www.google.com/search?q={word_list[i]}"
driver.get(url)
time.sleep(2)
html = driver.page_source
soup3 = BeautifulSoup(html)
if len(soup3.find_all(attrs={'id':'result-stats'})) > 0:
resultstats = soup3.find_all(attrs={'id':'result-stats'})[0].get_text()[7:soup3.find_all(attrs={'id':'result-stats'})[0].get_text().find(' res')]
freq = float(resultstats.replace(',',''))
else:
freq = 1000000000
print(word_list[i],freq )
cur.execute(f"INSERT INTO words_table VALUES ('{word_list[i]}', {freq})")
con.commit()
driver.close()
#
#for row in cur.execute('select * from words_table'):
# print(row)
#
con.close()
이제 크롤링은 끝.
'Diary' 카테고리의 다른 글
초밥전쟁 (0) | 2022.09.08 |
---|---|
청기와 타운을 방문하고 (0) | 2022.07.27 |
WORDLE helper 프로젝트(2) (0) | 2022.02.01 |
LP 입문 (0) | 2022.01.11 |
새해 첫 날 (1) | 2022.01.02 |