문제
자신이 백준 온라인 저지(BOJ)에서 맞은 문제의 수와 아이디를 그대로 출력하는 프로그램을 작성하시오.
첫 줄에 자신이 맞은 문제의 수, 둘째 줄에 아이디를 출력한다.
Python
print(f'{solved}\n{user}')
Javascript
console.log(`${solved}\n${user}`);
삽질
이 문제의 경우 단순한 출력을 위한 문제이기 때문에 별다른 코멘트가 없다.
처음에는 웹 페이지 파싱을 이용해서 얻는 문제인 줄 알고 시도했지만 계속 런타임 에러나 not found module이 계속 발생했다.
이것 저것 써보다가 안되겠다 싶어 구글링을 해보니 단순히 자신의 정보를 확인해서 적는 문제였다.
문제 난이도가 낮은 이유가 있었구나 싶었는데 이렇게 끝내는건 아쉬워 삽질한 코드를 적어본다.
# from bs4 import BeautifulSoup
from urllib import request
import gzip
user = '유저 아이디'
url = f'http://www.boj.kr/u/{user}'
hdr = { #헤드 정보 }
req = request.Request(url, data=None, headers=hdr)
fp = request.urlopen(req)
source = fp.read()
fp.close()
html_src= gzip.decompress(source).decode('utf-8')
# soup = BeautifulSoup(html_src, 'html.parser')
# target_tag = soup.find('span', id = 'u-solved')
# result = target_tag.get_text()
empty = html_src.split('u-solved')
empty = empty[1].split('<')[0]
result = empty.split('>')[-1]
print(f'{result}\n{user}')
# 으로 주석 처리를 한 부분은 BeautifulSoup를 사용했을 경우이고
그 아래의 더러운 empty 부분은 BeautifulSoup만 사용하지 않으면 가능할까 싶어서 시도했던 부분이다.
헤드 정보의 경우 없으면 403 Forbidden 에러가 발생해서 별도로 넣어주었다.
html_src= gzip.decompress(source).decode('utf-8')
처음 source를 얻었을 때 x16\x1c\x1e\xed\xb8\xd8\xa75u/\xb7dS\x1이런식으로 바이너리 형식으로 출력되어 utf-8으로 디코딩을 시도하였으나 UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte 오류가 발생하여 gzip으로 압축되어 있는건가 싶어 gzip 디코딩도 추가해주니 html_src를 문제없이 얻을 수 있었다.
# target_tag = soup.find('span', id = 'u-solved')
empty = html_src.split('u-solved')
유저 페이지에서 맞은 문제 수의 태그 속성을 확인해보니 파싱하기 쉽게 u-solved 아이디로 받고 있길레 그걸 기반으로 값을 얻을 수 있었다.
이전에 웹 파싱 연습을 할 때, decode를 했는데도 오류가 발생했어서 삽질을 하며 알아낸 gzip으로 압축되어있는 케이스를 만나는 등의 나름 재미있는 시간이였다.
'💻Develop > 💡Algorithm' 카테고리의 다른 글
#2231 분해합 (0) | 2023.07.20 |
---|---|
#8958 OX퀴즈 (0) | 2023.07.19 |
🌱#2753 윤년 (0) | 2023.07.19 |
🌱#14681 사분면 고르기 (0) | 2023.07.19 |
🌱#10699 오늘 날짜 (0) | 2023.07.12 |