본문 바로가기

프로젝트/Project1

Toy Project 1 (2) - 공정위 사이트 크롤링하기

데이터는 공정거래위원회 홈페이지의 불공정약관심사 - 보도자료를 사용할 것이다. 자료실에 시정명령 사건 목록도 있지만, 심결례에서 사건 처리 정보가 없는 경우도 많고 말 그대로 시정명령이기 때문에 정보도 부족하고 탐색하기 힘들다고 생각했다. 반면에 보도자료는 공정위에서 상세한 내용까지 공개를 하고 있는 정보이고, 실제로 읽어보면 약관의 어떤 부분이 변경되었는지 확인할 수 있기 때문에 보도자료 데이터를 사용하기로 했다. 이 부분은 공정위에 직접 전화를 해서 확인했다.

 

 

 

from selenium import webdriver
import time
import os
import shutil


driver = webdriver.Chrome('/Users/jason/Test/chromedriver')
driver.get('https://www.ftc.go.kr/www/ReportUserList.do?key=125&tribu_type_cd_S=100')
time.sleep(2)



## 웹 클릭 후 쉬기
def clickAndSleep(xpath, sleep_time):
    driver.find_element_by_xpath(xpath).click()
    time.sleep(1)

    
    

## 웹에서 파일 다운로드 할 때 2번째 파일이 있는지 체크
def hasxpath(xpath):
    try:
        driver.find_element_by_xpath(xpath)
        return True
    except:
        return False

    
    

file_num = 0
    
## 파일 다운로드 후 이름 재설정
def renameFile(file_type, file_num):
    ## 다운로드 위치
    Initial_path = '/Users/jason/Downloads'
    
    if file_type==True:
        filename = max([Initial_path + '/' + f for f in os.listdir(Initial_path)],key=os.path.getctime)
        shutil.move(filename,os.path.join(Initial_path,'term'+str(file_num)+'.hwp'))
        time.sleep(2)
    if file_type==False:
        filename = max([Initial_path + '/' + f for f in os.listdir(Initial_path)],key=os.path.getctime)
        shutil.move(filename,os.path.join(Initial_path,'term'+str(file_num)+'_'+'.hwp'))
        time.sleep(2)
    
    

    
    
## 파일을 찾아서 다운로드
def fileDownloads(table_num, file_num):
    ## 필요한 xpath
    download1 = """//*[@id="formx"]/fieldset/table/tbody/tr[3]/td/ul/li/a[1]/img"""
    download2 = """//*[@id="formx"]/fieldset/table/tbody/tr[3]/td/ul/li[2]/a[1]/img"""
    
    ## table_num에 해당하는 게시물 클릭해서 들어가기
    clickAndSleep('//*[@id="formx"]/fieldset[2]/table/tbody/tr['+str(table_num)+']/td[3]/a', 2)
    
    ## 파일 다운로드를 클릭했을 때 다운로드가 되지 않고 not found URL로 이동했을 때 처리하기 위한 변수
    check_URL = driver.current_url
    
    if hasxpath(download1):
        try:
            clickAndSleep(download1, 2)
            if check_URL != driver.current_url:
                driver.back()
            else:
                renameFile(True, file_num)
        except:
            driver.back()
            time.sleep(2)
        
    if hasxpath(download2):
        clickAndSleep(download2, 2)
        renameFile(False, file_num)
        
    driver.back()
    time.sleep(2)
    
    
    
    

## 웹 페이지에서 게시글 목록 탐색
def crawling():
    
    ## 필요한 xpath
    next2page = """//*[@id="contents"]/div/span[3]/a[2]"""
    global file_num
    file_num = 1
    
    ## 다음 페이지 리스트로 이동
    for next_page in range(3):
        ## 다음 페이지로 이동
        for page_num in range(1, 10):
            ## 다음 게시물로 이동
            for table_num in range(1, 11):
                ## 파일 다운로드 함수 호출하고, 저장된 파일 숫자 증가
                fileDownloads(table_num, file_num)
                file_num = file_num+1
            
            clickAndSleep('//*[@id="contents"]/div/span[2]/span/a['+str(page_num)+']', 2)
        
        clickAndSleep(next2page, 2)

    
    
    
    
## start crawling!!
crawling()

 

 

 

위의 코드로 셀레니엄을 이용하여 보도자료 페이지 크롤링을 했다. crawling 함수가 실행 되면 해당 페이지의 글 목록을 탐색하고 다음 페이지로 이동한다. 하나의 게시글에 들어가는 함수가 fileDownloads이다. 게시글에 들어가면 첨부된 파일을 클릭해서 다운로드한다. 여기서 좀 어려움을 겪었는데 파일들을 클릭했을 때 not found 페이지로 이동하는 경우가 너무 많았다. 그래서 파일을 클릭하기 전에 현재 게시글의 url을 저장해서 바뀌었을 때는 뒤로 가기를 하도록 만들어서 오류를 해결했다.

 

이 함수 내부에서는 renameFile과 hasxpath 함수를 사용한다. renameFile 함수는 다운로드 받은 파일을 1번부터 넘버링해서 파일 이름을 바꾼다. hasxpath는 다운로드 링크가 있는지 확인해서 없을 때 오류를 방지하기 위한 함수이다. 그리고 다운로드할 파일이 2개, 3개 있는 경우도 있는데 2번째 파일까지 확인해서 다운로드하는데 hasxpath가 사용된다.

 

위의 crawling을 실행해보면 (코드를 잘못짜서) 페이지를 건너뛰는 경우도 있고 네트워크 환경이나 작업 시간에 따라서 중간에 멈추는 경우가 많았다. 그래서 페이지 탐색하는 부분과 file num을 조금씩 수정하면서 2021~2006년의 모든 파일을 다운로드하였다.

 

 

 

 

 

이제 다음 시간에 다운로드 중 에러가 발생한 0바이트 파일들을 삭제하고 hwp 파일을 txt 파일로 변경하는 작업을 할 것이다.