인공지능 공부/남박사의 파이썬 실전

(인프런) 실전 파이썬 영어기사 크롤링해서 영어단어게임 만들기

앨런튜링_ 2021. 6. 3. 00:36
from math import trunc
import requests
from bs4 import BeautifulSoup
import re ##정규식 라이브러리 (따로 검색해서 공부해보자)
import os
import json
import random

from requests.api import get 

##사이트를 파싱해오기 
url = "https://www.usatoday.com"
r = requests.get(url)
bs = BeautifulSoup(r.text, "lxml")
lists = bs.select(".gnt_m_th_a")

##뉴스기사 읽어오기 
def get_news():
    for li in lists:
        href = url + li["href"]
        r = requests.get(href)
        bs = BeautifulSoup(r.text, "lxml")
        texts = bs.select("div.gnt_ar_b > p.gnt_ar_b_p")
        
        contents = [p.text for p in texts]
        contents = " ".join(contents)
        ##for문 종료해주기 단어게임을 위해 소문자로 전환
        return contents.lower()
    ##오류로인해서 리스트를 못구해올 경우 None 리턴 
    return None
    
def naver_translate(word):
    try:
        url = "https://ac-dict.naver.com/enko/ac?st=11&r_lt=11&q={}".format(word)
        r = requests.get(url)
        j = json.loads(r.text)
        return (j["items"][0][0][2][0])
    except:
        return None

def make_quize(news):
    ##\b는 경계를 의미 
    ##이건 \역슬래쉬를 무시하고 a~z까지 중에 4자리에서 15자리까지만 뽑아와라 왜냐면 of the 이런건 단어게임에 의미가 없음
    match_pattern=re.findall(r'\b[a-z]{4,15}\b',news) ##정규식은 패턴을 뽑아오기 위해 사용한다 Parsing 테크닉에 날개를 달아주는 라이브러리

    frequency = {} #위에서 얻은 단어를 단어 : count 로 숫자를 알기 위해 딕셔너리 생성
    quize_list = [] #얻은 값들을 한국어로 변환시키기 위한 리스트

    for word in match_pattern:
        count = frequency.get(word, 0) ##없는 경우에 default 값이 0으로 설정함
        frequency[word]  = count +1


    ##딕셔너
    for word, count in frequency.items():
        if count > 1:
            kor = naver_translate(word) ##번역을 해야함 API를 쓸 수도 있음 하지만 네이버에 영어사전을 크롤링해서 만들자
            
            if kor is not None:
                quize_list.append({kor : word})
    return quize_list

##게임 실행 함수
def quize():
    quize_list = make_quize(get_news()) ##예외처리가 안되서 지향하는 방식은 아니다
    random.shuffle(quize_list)

    chance  = 5
    count = 0
    for q in quize_list:
        os.system("cls")
        count +=1
        kor = list(q.keys())[0] #딕셔너리의 형태라서 한글로 쏙 ! 캐스팅
        english = q.get(kor)

      
        print("*" *90)
        print("문제:{}".format(kor))
        print("*" *90)

        for j in range(chance):
            user_input = str(input("위의 뜻이 의미하는 단어를 입력하세요>")).strip().lower()

            if user_input == english:
                print("정답입니다!! {} 문제 남음".format(len(quize_list)-count))
                os.system("pause")
                break
            else:
                n = chance - (j+1)
                if j == 0:
                    print("{}가 아닙니다. {}번 기회가 남았습니다.".format(user_input, n))
                elif j ==1:##힌트 주기
                    print("{}가 아닙니다. {}번 기회가 남았습니다. 힌트 {}로 시작".format(user_input, n, english[0]))
                elif j ==2:##힌트 주기
                    hint = " _ "*int(len(english) -2)
                    print("{}가 아닙니다. {}번 기회가 남았습니다. 힌트 {} {} {}로 시작".format(user_input, n, english[0], english[1], hint))
                elif j ==3:##힌트 주기
                    hint = " _ "*int(len(english) -3)
                    print("{}가 아닙니다. {}번 기회가 남았습니다. 힌트 {} {} {} {}로 시작".format(user_input, n, english[0], english[1], english[2], hint))
                else:
                    print("틀렷습니다. 정답은 {}입니다.".format(english))
                    os.system("pause")
    print("더이상 문제가 없습니다.")
quize()