기록방

백준 문제 크로스체크 프로그램 본문

웹 크롤링

백준 문제 크로스체크 프로그램

Soom_1n 2022. 10. 1. 19:16
💡 백준 그룹에서 문제 낼 때, 다른 구성원이 이미 풀 었던 문제인지 확인하기 어렵다. 웹 크롤링으로 해결해보자!
  • urllib.request 와 BeautifulSoup 를 이용해 웹 크롤링과 파싱을 진행한다.
  • 옵션을 선택해 기능을 사용할 수 있도록 한다.
    • 웹 크로링 매번 실행 후 문제 개수 출력
    • 입력한 문제가 크롤링 된 목록에 포함 되는지 출력
    • 무한 반복문을 활용하고, 종료와 오타방지 기능 추가
# 백준에서 이미 풀은 문제를 조회해, 아직 안 풀은 문제인지 출력하는 프로그램

import urllib.request
from bs4 import BeautifulSoup

def find_problem(find_id):
    # 너무 많이 접속하면 차단되므로 이상한 접속이 아님을 헤더로 밝힘
    header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'}

    # 백준 유저 페이지(맨 뒤에 아이디 추가)
    url = "https://www.acmicpc.net/user/"

    for i in find_id:
        print("find : ", i)
        req = urllib.request.Request(url =(url+i), headers=header)  # 리퀘스트 생성
        url_open = urllib.request.urlopen(req)                      # url 접속
        bs_obj = BeautifulSoup(url_open, "html.parser")             # html 파싱
        problem_list = bs_obj.find("div", {"class", "problem-list"})# 문제 a태그 리스트
        for pl in problem_list:
            problem.add(pl.text)

# 푼 문제를 찾을 아이디
find_id = ['yoon6763', 'kangsm423', 'iomanip0107', 'apircity', 'spalqj56', 'iamdek', 'digh0515']

print("==================================\n\n\t백준 문제 크로스체크 프로그램\n\n==================================\n")
problem = set()

while True:
    print(" 1) 푼 문제 리스트 불러오기\t2) 풀었던 문제인지 조회\t3) 종료")
    order = input("실행할 번호를 입력하세요 : ")

    if order == '1':
        print("\n>> 푼 문제 리스트 불러오기\n")
        find_problem(find_id)
        print("\n문제 총 개수 :", len(problem))
    elif order == '2':
        print("\n>> 풀었던 문제인지 조회")
        if len(problem) == 0:
            print("\n먼저 푼 문제 리스트를 불러와주세요.")
        else:
            while True:
                pb_list = input("\n검색할 번호 입력(복수는 공백으로 구분, 공백으로 종료) : ").split()
                if len(pb_list) == 0:
                    break
                flag = True
                for pb in pb_list:
                    if pb in problem:
                        print(pb,"는 이미 풀었습니다.")
                        flag = False
                if flag:
                    print("모두 풀지 않은 문제입니다.")
    elif order == '3':
        print("\n>> 종료")
        break
    else:
        print("\n>> 잘못된 숫자를 입력")
    input("\n[Enter]")
    print("\n==================================\n")

실행 결과


업데이트 : 문제 리스트를 파일로 입력

포스팅 추가로 인한 업데이트

 

백준 문제 등급 별 목록 가져오기

 

백준 문제 등급 별 목록 가져오기

# sovled.ac 레벨 별 문제리스트 파일 저장(레벨별 공백 구분) import urllib.request from bs4 import BeautifulSoup import time import random def find_problem(url): print(url) temp = set() # 너무 많이 접..

soooom.tistory.com

# 백준에서 이미 풀은 문제를 조회해, 아직 안 풀은 문제인지 출력하는 프로그램

import sys
import urllib.request
from bs4 import BeautifulSoup

def find_problem(find_id):
    # 너무 많이 접속하면 차단되므로 이상한 접속이 아님을 헤더로 밝힘
    header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36'}

    # 백준 유저 페이지(맨 뒤에 아이디 추가)
    url = "https://www.acmicpc.net/user/"

    for i in find_id:
        print("find : ", i)
        req = urllib.request.Request(url =(url+i), headers=header)  # 리퀘스트 생성
        url_open = urllib.request.urlopen(req)                      # url 접속
        bs_obj = BeautifulSoup(url_open, "html.parser")             # html 파싱
        problem_list = bs_obj.find("div", {"class", "problem-list"})# 문제 a태그 리스트
        for pl in problem_list:
            problem.add(pl.text)



# 푼 문제를 찾을 아이디
# find_id = ['yoon6763', 'kangsm423', 'iomanip0107', 'apircity', 'spalqj56', 'iamdek', 'digh0515']
find_id = []

print("==================================\n\n\t백준 문제 크로스체크 프로그램\n\n==================================\n")
problem = set()
level_problem = []

while True:
    print(" 1) 푼 문제 리스트 불러오기  2) 크로스 체크  3) 아이디 추가  4) 레벨별 문제 파일 불러오기  0) 종료")
    order = input("실행할 번호를 입력하세요 : ")

    if order == '1':
        print("\n>> 푼 문제 리스트 불러오기\n")
        find_problem(find_id)
        print("\n문제 총 개수 :", len(problem))


    elif order == '2':
        if len(problem) == 0:
                print("\n먼저 푼 문제 리스트를 불러와주세요.\n")
        else:
            order = input("\n>>  1) '문제 텍스트 파일' 크로스체크\t 2) '직접 입력' 크로스체크\n")
            if order == '1':
                level = ""
                level_list = ['B', 'S'] # 브론즈, 실버만 구현

                # 텍스트 파일 읽어오기
                print("\n 문제 리스트 파일 읽는 중...",end="")
                f = open("D:\github\CodingTest\problem_list.txt",'r')
                line_temp = []

                lines = f.readlines()

                for line in lines:
                    line = line.rstrip()
                    if line == '':
                        level_problem.append(line_temp)
                        line_temp = []
                    else:
                        line_temp.append(line)
                print("완료\n")

                # 크로스체크
                while level != " ":
                    level = input('레벨을 입력하세요(ex. B1 / 종료:공백):')
                    if len(level)!=2 or level[0] not in level_list:
                        print('잘못입력하셨습니다.')
                    else:
                        idx = level_list.index(level[0])+(5-int(level[1]))
                        print("\n-----level", level, "에서 풀지않은 문제 리스트-----")
                        for p in level_problem[idx]:
                            if p not in problem:
                                print(p)
                        print("\n------------------------------------------")
            elif order == '2':
                print("\n>> 풀었던 문제인지 조회")
                while True:
                    pb_list = input("\n검색할 번호 입력(복수는 공백으로 구분, 공백으로 종료) : ").split()
                    if len(pb_list) == 0:
                        break
                    flag = True
                    for pb in pb_list:
                        if pb in problem:
                            print(pb,"는 이미 풀었습니다.")
                            flag = False
                    if flag:
                        print("모두 풀지 않은 문제입니다.")
            else:
                print('잘못입력하셨습니다.')


    elif order == '3':
        order = input("\n>>  1) 공백 구분\t 2) 줄바꿈 구분(종료 : 0)\n")
        temp = []
        if order == '1':
            temp = sys.stdin.readline().rstrip().split()
        elif order =='2':
            ss = ""
            while ss != "0":
                ss = input()
                temp.append(ss)
        else:
            print('잘못입력하셨습니다.')
        for i in temp[:-1]:
            id = i.replace(" ","")
            if id not in find_id and id != "":
                find_id.append(id)
        print(find_id)


    elif order == '0':
        print("\n>> 종료")
        break
    else:
        print("\n>> 잘못된 숫자를 입력")
    input("\n[Enter]")
    print("\n==================================\n")
  • 백준 문제를 레벨별로 저장한 텍스트 파일에서 안푼 문제를 찾아주는 기능을 추가함

B5를 입력하면 B5문제 중 풀지않은 번호만 출력

728x90

'웹 크롤링' 카테고리의 다른 글

백준 문제 등급 별 목록 가져오기  (0) 2022.10.13
파이썬 웹 크롤링 교재 #3  (0) 2022.09.29
파이썬 웹 크롤링 교재 #2  (0) 2022.09.21
파이썬 웹 크롤링 교재 #1  (0) 2022.09.21