저의 목표를 이루기 위해서 한걸음씩 걸어가며 그 과정을 기록하기 위해 블로그를 시작합니다!
백준 크롤링(Request, beautifulsoup)모듈을 이용한 웹 크롤링 코드.
Python IDE: PyCharm
기본 코드 설명:
1. 백준의 url은 404로 크롤링을 막아놓은듯함.(headers user-Agent)이용하여 우회한다.
2. request를 이용하여 정상(200)일 경우 text로 변환후 bs4의 soup을 이용하여
필요한 태그들을 각 변수에 저장
3. for문을 이용하여 td태그를 찾는다
4. 저장된 td태그중에 a태그를 찾는다(title) -> Problem Index와 Title을 나타냄
5. user에게 입력을 받는다
6. 입력된 값이 1 <= or <= 100일 경우 rnage(1000,1101) 코드를 이용하여 변환한다
EX) INPUT = 5 -> OUTPUT = 1005(Baekjun Problem Index)
설명: 코드를 실행해보면 문제의 인덱스는 1 ~ 100이다 하지만 백준의 문제는 1000 ~ 1005이다
그래서 5번을 입력한다면 1005번이 저장되게 만듦.
7. 백준의 기본 문제 url = 'https://www.acmicpc.net/problemset'
백준의 선택된 문제 url EX(5) = 'https://www.acmicpc.net/problem/1005'
url을 보면 서로 다르다. 그러기 떄문에 선택된 문제 url을 한번더 정의후
사용자가 입력한 5번(1005)번이 변환되어 1005가 되고
merged_url = problem_url + str(intger_comp_code)
responses = requests.get(merged_url,headers=headers)
변환된 1005을 comp_code에 저장후 동적으로 변환되게 한후 integer_comp_code에
저장후 코드를 합친후 headers을 이용하여 우회한다
그 밑 코드는 문제를 직접 긁어오는 웹 태그들이다.
Code:
import requests
import os
from bs4 import BeautifulSoup
def clear():
os.system('cls' if os.name == 'nt' else 'clear')
def baekjoon_crwl():
empty_result = []
url = 'https://www.acmicpc.net/problemset'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'}
response = requests.get(url, headers=headers)
if response.status_code == 200:
html = response.text
soup = BeautifulSoup(html, 'html.parser')
data = soup.find('div', {"class": "table-responsive"})
body = data.find('tbody')
links = body.find_all("tr")
for link in links:
save_index = int(link.find("td").text)
empty_result.append(save_index) # Original index
for index, link in enumerate(links,start=1):
title = link.find("a").text # TITLE!
print(f"{index}. {title}", sep=' ') # print problem list.
comp_code = [] # comparison code
fetch_problem = [] # fetch problem dynamically
selected_problem = int(input('Please select a problem:'))
print('\n\n')
return comp_code, fetch_problem, selected_problem, headers
def baekjoon_crwl_2(comp_code, fetch_problem, selected_problem, headers):
if 1 <= selected_problem <= 100:
step_list = list(range(1000, 1101))
comp_code.append(step_list[selected_problem])
fetch_problem.append('<a href="/problem/{0}"></a>'.format(comp_code[0]))
fetch_problem = (''.join(list(map(str, fetch_problem)))) # Change to string type
print('TAG: ',fetch_problem)
integer_comp_code = (int(comp_code[0])) # Integer comp code
problem_url = 'https://www.acmicpc.net/problem/'
merged_url = problem_url + str(integer_comp_code) # Integer.
responses = requests.get(merged_url,headers=headers)
clear()
if responses.status_code == 200:
html = responses.text
soup = BeautifulSoup(html, 'html.parser')
problem_description = soup.select('#problem_description > p')
problem_ul = soup.select('#problem_description > ul')
input_description = soup.select('#problem_input > p')
output_description = soup.select('#problem_output > p')
sample_i = soup.select("pre[id^=sample-input]")
sample_o = soup.select("pre[id^=sample-output]")
print("Problem Number:", integer_comp_code)
print('\n')
print('Problem:')
for i in problem_description:
print(i.text.strip(), end='\n\n')
for i in problem_ul:
print(i.text.strip(), end='\n\n')
print('\n\n')
print("입력:")
for i in input_description:
print(i.text.strip(), end='\n\n')
print("출력:")
for i in output_description:
print(i.text.strip(), end='\n\n')
print("에시:")
for i in range(len(sample_i)):
print('IN:')
print(sample_i[i].text.strip(), end='\n\n')
print('OUT:')
print(sample_o[i].text.strip(), end='\n\n')
if __name__ == "__main__":
comp_codes, fetch_problems, selected_problems, headerss = baekjoon_crwl()
clear()
baekjoon_crwl_2(comp_codes, fetch_problems, selected_problems, headerss)
살면서 일기도 제대로 써보지 않아 글솜시가 많이 부족합니다.
이해가 안가는 부분이 많을지도 모르겠네요
봐주셔서 감사합니다
mer_bleue.
참고 블로그: