Program Language/Python

(python) 정부 입찰 공고 자료 수집

야곰야곰+책벌레 2023. 11. 23. 16:04
728x90
반응형
import selenium # 여기서는 약자를 붙이지 않았다.
import pandas as pd
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
import time

service = Service(ChromeDriverManager().install())
options = Options()
options.add_argument("--start-maximized")

driver = webdriver.Chrome(service=service, options=options) # 우선 경로나 옵션을 넣으면 동작 하지 않음 (해결 안됨)
driver.maximize_window() # 창을 최고 사이즈로 함

# 셀레니움 클래스를 이용함.
from selenium.webdriver.common.by import By

pageCount = 5
tb_list = []

for i in range(pageCount) :
    url = 'https://www.g2b.go.kr:8101/ep/tbid/tbidList.do?area=&bidNm=&bidSearchType=1&\
fromBidDt=2023/08/24&fromOpenBidDt=&instNm=&radOrgan=1&regYn=Y&searchDtType=1&searchType=1&\
taskClCds=5&toBidDt=2023/11/23&toOpenBidDt=&currentPageNo=' + str(i+1) + '&maxPageViewNoByWshan=2&'
    driver.get(url) # 입찰공고
    
    time.sleep(1) # 검색 시간 필요
    tb = driver.find_element(By.XPATH, '//*[@id="resultForm"]/div[2]/table/tbody') # 결과 객체로 가져오기
    tb_row = tb.find_elements(By.TAG_NAME, 'tr') # 결과 객체로 가져오기

    for idx, value in enumerate(tb_row) :
        data_0 = value.find_elements(By.TAG_NAME, 'td')[0] # 업무
        data_1 = value.find_elements(By.TAG_NAME, 'td')[1] # 공고번호
        data_2 = value.find_elements(By.TAG_NAME, 'td')[2] # 분류
        data_3 = value.find_elements(By.TAG_NAME, 'td')[3] # 공고명
        data_4 = value.find_elements(By.TAG_NAME, 'td')[4] # 공고기관
        data_5 = value.find_elements(By.TAG_NAME, 'td')[5] # 수요기관
        data_6 = value.find_elements(By.TAG_NAME, 'td')[6] # 계약방법
        data_7 = value.find_elements(By.TAG_NAME, 'td')[7] # 입력일시
        data_8 = value.find_element(By.TAG_NAME, 'a') # 원문주소
        tb_list = tb_list + [[data_0.text, data_1.text, data_2.text, data_3.text, data_4.text, data_5.text, data_6.text,
                              data_7.text.split('\n')[0], data_7.text.split('\n')[1], data_8.get_attribute('href')]]

# 최근공고일시를 저장한 텍스트 파일 안에 공고일시를 변수로 저장
f = open("최근공고일.txt", 'r')
ann_date = f.readline()
f.close()      
  
df_result = pd.DataFrame.from_records(tb_list, columns=['업무', '공고번호', '분류', '공고명', '공고기관', '수요기관', '계약방법', '입력일시', '입찰마감일시', '원문주소'])
df_result = df_result.sort_values(by = ['입력일시'], ascending=False)

# 공고일시 이후 공고만 조회 결과로 남기기
for i in range(len(df_result))[::-1] :
    if df_result.iloc[i]['입력일시'] <= ann_date :
        df_result = df_result.drop(i)

print(df_result)


# 원문 첨부파일 내려 받기
for i in range(len(df_result)) :
    ann_url = df_result.iloc[i]['원문주소']
    driver.get(ann_url)
    
    try :
        tbl_1 = driver.find_element(By.CLASS_NAME, 'table_list_attchFileTbl') # 결과 객체로 가져오기
        
        if "첨부된 파일이 없습니다" in tbl_1.text :
            continue
        else :
            tbl_1_body = tbl_1.find_element(By.TAG_NAME, 'tbody')
            tbl_1_body_row = tbl_1_body.find_elements(By.TAG_NAME, 'tr')
            
            for idx, value in enumerate(tbl_1_body_row) :
                file_name = value.find_elements(By.TAG_NAME, 'td')[2]
                if file_name.text[-4:] != 'html' :
                    file_name.find_element(By.TAG_NAME, 'a').click()
                    time.sleep(1)
        
    except:
        continue
    
import os
from os import listdir
from os.path import isfile, join
import shutil

def getFileList(path) :
    return [[join(path,i),i] for i in listdir(path) if isfile(join(path, i))]

files = getFileList("C:/Users/사용자/Downloads") # 다운로드 위치
df_file = pd.DataFrame(files, columns=['path', '파일명'])

ann_filepath = []
for i in df_file['path'] :
    if any(j in i for j in df_result['공고번호']) :
        ann_filepath = ann_filepath + [i]
        
base_dir = os.getcwd()
for i in df_result['공고번호'] :
    path = join(base_dir, i)
    os.mkdir(path)
    
for i in ann_filepath :
    shutil.move(i, base_dir + "\\" + i[32:46]) # 사용자 이름에 따라 변경

f = open("최근공고일시.txt", 'w')
ann_date = f.write('{}'.format(df_result['입력일시'][0]))
f.close()

time.sleep(1)
728x90
반응형