저의 목표를 이루기 위해서 한걸음씩 걸어가며 그 과정을 기록하기 위해 블로그를 시작합니다!
백준 크롤링(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.

참고 블로그:

  1. https://url.kr/rn1lyi

  2. https://url.kr/czq86k

    
profile
목표를 이루기 위해 한걸음씩 걸어가는 대학생입니다

0개의 댓글