# import data handling libraries
import pandas as pd
import numpy as np


# 셀레니움 드라이버 임포트
import selenium

# 웹드라이버 임포트
from selenium import webdriver
from selenium.webdriver.common.by import By # WebDriverWait는 Selenium 2.4.0 이후 부터 사용 가능합니다.
from selenium.webdriver.support.ui import WebDriverWait  # expected_conditions는 Selenium 2.26.0 이후 부터 사용 가능합니다.
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.common.exceptions import ElementNotVisibleException
from selenium.webdriver.common.keys import Keys

# BeautifulSoup 임포트 
from bs4 import BeautifulSoup

# time 임포트
import time

# 크롬 창 크기를 최대화 한다.
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
driver = webdriver.Chrome('chromedriver.exe',chrome_options=options)


#페이지수 
페이지수 = 5 # 이 부분은 about 개념이다. 

#페이지수로 loop
테이블_리스트 = []


for i in range(페이지수) :
    공고_URL = 'http://www.g2b.go.kr:8101/ep/tbid/tbidList.do?area=&bidNm=&bidSearchType=1&fromBidDt=2020%2F08%2F03&fromOpenBidDt=&instNm=&radOrgan=1&regYn=Y&searchDtType=1&searchType=1&taskClCds=5&toBidDt=2020%2F09%2F02&toOpenBidDt=&currentPageNo=' + str(i+1) +'&maxPageViewNoByWshan=2&'     
    driver.get(공고_URL)
#    테이블 = driver.find_element_by_class_name('table_list_tbidTbl').click()
    테이블_바디 = driver.find_element_by_xpath('//*[@id="resultForm"]/div[2]/table/tbody')
    테이블_바디_행 = 테이블_바디.find_elements_by_tag_name("tr")

    for idx, value in enumerate(테이블_바디_행):
        데이터_0 = value.find_elements_by_tag_name("td")[0]
        데이터_1 = value.find_elements_by_tag_name("td")[1]
        데이터_2 = value.find_elements_by_tag_name("td")[2]
        데이터_3 = value.find_elements_by_tag_name("td")[3]
        데이터_4 = value.find_elements_by_tag_name("td")[4]
        데이터_5 = value.find_elements_by_tag_name("td")[5]
        데이터_6 = value.find_elements_by_tag_name("td")[6]
        데이터_7 = value.find_elements_by_tag_name("td")[7]
        데이터_8 = value.find_element_by_tag_name('a')
    
        print(데이터_0.text, 
              데이터_1.text,
              데이터_2.text,
              데이터_3.text,
              데이터_4.text,
              데이터_5.text,
              데이터_6.text,
              데이터_7.text,
              데이터_8.get_attribute('href'))
        테이블_리스트 = 테이블_리스트 + [[데이터_0.text, 데이터_1.text, 
                                 데이터_2.text, 데이터_3.text, 
                                 데이터_4.text, 데이터_5.text, 
                                 데이터_6.text, 데이터_7.text.split('\n')[0], 
                                 데이터_7.text.split('\n')[1],
                                 데이터_8.get_attribute('href') ]]    

# 결과를 엑셀로 저장하기 : list of list 는 from_records() 함수를 이용한다. 
df_조회결과 = pd.DataFrame.from_records(테이블_리스트, columns=['업무', 
                                                   '공고번호', 
                                                   '분류', 
                                                   '공고명', 
                                                   '공고기관', 
                                                   '수요기관', 
                                                   '계약방법', 
                                                   '입력일시', 
                                                   '입찰마감일시',
                                                   '원문주소'] )


# 입력일시로 내림차순
df_조회결과 = df_조회결과.sort_values(by = ['입력일시'], ascending = False)


# 최근공고일시.txt에서 입력된 공고일시를 임시 변수로 저장한다.
f = open("최근공고일시.txt", 'r')
구_공고일시 = f.readline()
print(구_공고일시)
f.close()


# 구_공고일시 이후 공고만 나라장터조회결과.tbl에 남기기
for i in range(len(df_조회결과))[::-1]:
    if df_조회결과.iloc[i]['입력일시'] <= 구_공고일시 :
        df_조회결과 = df_조회결과.drop(i)
        
# 공고 상세 URL에 반복해서 접속하하고 첨부파일 다운로드 받기
for i in range(len(df_조회결과)):
    공고_URL = df_조회결과.iloc[i]['원문주소'] 
    driver.get(공고_URL)
    
    # 테이블을 클래스 이름으로 찾는다.
    try :
        테이블_1 = driver.find_element_by_class_name('table_list_attchFileTbl') #element 단수 조심
    
        if "첨부된 파일이 없습니다" in 테이블_1.text:
            continue 
    
        else :
            테이블_1_바디 = 테이블_1.find_element_by_tag_name("tbody")  #element 단수 조심
            테이블_1_바디_행 = 테이블_1_바디.find_elements_by_tag_name("tr") #elements 복수 조심

            for idx, value in enumerate(테이블_1_바디_행):
                파일명 = value.find_elements_by_tag_name("td")[2]
                if 파일명.text[-4:] != 'html' :
                    파일명.find_element_by_tag_name("a").click()
                    time.sleep(1)
                    
    except :
        continue 

# 
import os
import shutil
from os import listdir
from os.path import isfile, join

#
pd.set_option('display.max_columns', None)  

# 사용자 정의 함수
def getFileList(path):
    return [[join(path,i),i] for i in listdir(path) if isfile(join(path,i))]

files =getFileList("C:/Users/사용자/Downloads/") # 사용자 다운로드 폴더 경로는 적절하게 수정필요
#print(files)
df_다운로드파일 = pd.DataFrame(files,columns = ['path','파일명'])
print(df_다운로드파일)

#다운로드파일 = Table(data = df_다운로드파일)

# 공고파일 path 찾기 : DrProof가 파일명에 포함된 것만 찾기
공고파일_path = []

for i in df_다운로드파일['path'] :
    if any(j in i for j in df_조회결과['공고번호']) :
        공고파일_path = 공고파일_path + [i]

# 디렉토리 생성
베이스_디렉토리 = os.getcwd()

for i in df_조회결과['공고번호'] :
    path = join(베이스_디렉토리, i)
    os.mkdir(path)


for i in 공고파일_path :
    shutil.move(i, 베이스_디렉토리+"\\"+i[27:41])   # 베이스 디렉토리의 크기에 따라 [27:41] 부분은 적절하게 수정 필요

첨부파일

엑셀비교.py
0.00MB
분개장차이.xlsx
0.01MB
분개장.csv
1.56MB
재무제표.csv
0.00MB
분개장_1.xlsx
1.08MB
분개장_2.xlsx
1.08MB

import pandas as pd
import numpy as np
import xlwings as xw
pd.set_option('display.max_columns', None)  

# 신구 엑셀 명명
구엑셀 = '분개장_1.xlsx'
신엑셀 = '분개장_2.xlsx'

# 데이터프레임으로 변환
df_old = pd.read_excel(구엑셀, 'Sheet1', na_values=['NA'])
df_new = pd.read_excel(신엑셀, 'Sheet1', na_values=['NA'])

# 버전 칼럼 삽입
df_old['version'] = 'old'
df_new['version'] = 'new'

# groupby 
gb_old = df_old.groupby(['전표일자','전표번호'])
gb_new = df_new.groupby(['전표일자','전표번호'])

df_old['전표번호seq'] = gb_old.cumcount()
df_new['전표번호seq'] = gb_new.cumcount()

# 
df_old['version'] = 'old'
df_new['version'] = 'new'


#각 DataFrame에 '전표일자번호' 칼럼을 만들고 아래와 같이 전표일자, 전표번호, 전표번호seq를 조합해서 고유한 번호로 넣는다.
df_old['전표일자번호'] = df_old['전표일자'] + df_old['전표번호'].astype(str) + df_old['전표번호seq'].astype(str)
df_new['전표일자번호'] = df_new['전표일자'] + df_new['전표번호'].astype(str) + df_new['전표번호seq'].astype(str)

#각 DataFrame에 '전표일자번호' 칼럼에 set() 함수를 취하여 중복을 제외한 것을 변수로 설정한다.
old_전표일자번호_all = set(df_old['전표일자번호'])
new_전표일자번호_all = set(df_new['전표일자번호'])

#삭제_전표일자번호와 추가_전표일자번호 변수를 아래와 같이 설정한다. 세트끼리 (-) 연산자를 취하는 경우 앞의 세트의 원소에서 뒤의 세트의 원소를 차감한 세트를 반환한다.
삭제_전표일자번호 = old_전표일자번호_all - new_전표일자번호_all
추가_전표일자번호 = new_전표일자번호_all - old_전표일자번호_all

# 각 df_old를 위로, df_new를 아래로 합친다.
all_data = pd.concat([df_old,df_new],ignore_index=True)

# all_data에서 subset의 항목이 모두 중복인 것을 제외하여 중복되지 않은 항목만 남긴다
changes = all_data.drop_duplicates(subset=["전표일자","전표번호", "계정코드", "계정과목",
                                           "차변금액","대변금액", "거래처", "승인일자", "프로젝트코드", "전표일자번호"],
                                           keep=False)
                                           
# old와 new를 각각의 DataFrame으로 구분한다.
change_new = changes[(changes["version"] == "new")]
change_old = changes[(changes["version"] == "old")]


# 각각의 DataFrame에서 version 칼럼을 삭제한다.
change_new = change_new.drop(['version'], axis=1)
change_old = change_old.drop(['version'], axis=1)

# 각각의 DataFrame에서 전표일자번호를 새로운 인덱스로 변경한다. 
change_new.set_index('전표일자번호', inplace=True)
change_old.set_index('전표일자번호', inplace=True)



# change_old와 change_new를 아래와 같이 combine한다.

df_all_changes = pd.concat([change_old, change_new],
                            axis=1,
                            keys=['old', 'new'],
                            join='outer')


# Define the diff function to show the changes in each field
def report_diff(x):
    return x[0] if x[0] == x[1] else '{} ---> {}'.format(*x)
    
    
df_all_changes = df_all_changes.swaplevel(axis=1)[change_new.columns[0:]]
    
df_changed = df_all_changes.groupby(level=0, axis=1).apply(lambda frame: frame.apply(report_diff, axis=1))

# 칼럼순서 변경
cols = list(change_new.columns)
df_changed = df_changed[cols] 
df_changed = df_changed.reset_index()


df_removed = changes[changes["전표일자번호"].isin(삭제_전표일자번호)]
df_added = changes[changes["전표일자번호"].isin(추가_전표일자번호)]


dfs = [df_changed, df_removed, df_added]

#총괄 view
베이스_디렉토리 = os.getcwd()

wb = xw.Book(베이스_디렉토리 + '\\분개장차이.xlsx')
    
for i in range(len(dfs)):
    sht = wb.sheets[i]
    sht.range('A1').value = dfs[i]

첨부파일 

다트재무정보파싱.py
0.00MB
종목코드.xlsx
0.06MB

import dart_fss as dart

# Open DART API KEY 설정
api_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'  

dart.set_api_key(api_key=api_key)


# 
베이스_디렉토리 = os.getcwd()

# 종목코드 엑셀을 불러와서 DataFrame으로 만들기
df_종목코드 = pd.read_excel(베이스_디렉토리 + '\\종목코드.xlsx')

# 검색 칼럼이 1인 것만 필터링
df_종목코드 = df_종목코드[df_종목코드['검색'] == 1]
df_종목코드 = df_종목코드.reset_index()



# DART 에 공시된 회사 리스트 불러오기
corp_list = dart.get_corp_list()

# 
for i in range(len(df_종목코드)):
    개별종목명 = df_종목코드.loc[i, '회사명']

    # 개별회사 검색
    개별회사 = corp_list.find_by_corp_name(개별종목명, exactly=True)[0]


    # 2012년부터 연간 연결재무제표 불러오기
    fs = 개별회사.extract_fs(bgn_de='20180101')


    # 재무제표 검색 결과를 엑셀파일로 저장 ( 기본저장위치: 실행폴더/fsdata )
    fs.save()

첨부파일 

상장주식베타구하기.py
0.00MB
종목코드.xlsx
0.06MB

import pandas as pd
import numpy as np

# 라이브러리 불러오기
import FinanceDataReader as fdr
import xlwings as xw
pd.set_option('display.max_columns', None)  

# 베이스 디렉토리 설정
베이스_디렉토리 = os.getcwd()

# 종목코드 엑셀을 불러와서 DataFrame으로 만들기
df_종목코드 = pd.read_excel(베이스_디렉토리 + '\\종목코드.xlsx')

# 검색 칼럼이 1인 것만 필터링
df_종목코드 = df_종목코드[df_종목코드['검색'] == 1]
df_종목코드 = df_종목코드.reset_index()

# 기준일
시작일자 = '2019-01-01'
종료일자 = '2020-09-07'


# for 문

테이블_리스트 = []

for i in range(len(df_종목코드)):

    개별종목코드 = df_종목코드.loc[i, '종목코드']
    개별종목명 = df_종목코드.loc[i, '회사명']
    df_개별종목 = fdr.DataReader(개별종목코드, 시작일자, 종료일자)

    # KOSPI 200 list
    df_코스피지수 = fdr.DataReader('KS11', 시작일자, 종료일자)

    # df의 Date와 Close, 코스피지수 Date와 Close만 갖고 옴
    df_종가_변동 = df_개별종목['Change']
    df_코스피지수_종가_변동 = df_코스피지수 ['Change']
    
    # 조인
    df_조인 = pd.merge(df_종가_변동, df_코스피지수_종가_변동, how='left', 
                     left_on = ['Date'], right_on = ['Date'],suffixes=('_개별', '_코스피지수'))
                     
    
    
    # 베타 구하기                 
    공분산_개별_코스피 = df_조인.cov().iloc[0]['Change_코스피지수'] 
    분산_코스피 = df_조인['Change_코스피지수'].var()
    베타 = 공분산_개별_코스피/분산_코스피
    
    print('종목코드 {} {}의 {}일부터 {}일까지 KOSPI 대비 daily B(베타)는 {:.2f} 입니다.'.format(개별종목코드,개별종목명,시작일자,종료일자,베타)) 
    테이블_리스트 = 테이블_리스트 + [[개별종목코드, 개별종목명, 시작일자, 종료일자, 베타]]
    
    df_베타결과 = pd.DataFrame.from_records(테이블_리스트, columns = ['개별종목코드', '개별종목명', '시작일자', '종료일자', '베타'])

    # 주가 및 변동 history 테이블 구하기  
    df_종가변동_조인 = pd.merge(df_개별종목, df_코스피지수, how='left', 
                     left_on = ['Date'], right_on = ['Date'],suffixes=('_{}'.format(개별종목명), '_코스피지수'))

    # 주가 및 변동 history 테이블에서 필요한 칼럼 선택
    df_종가변동_조인 = df_종가변동_조인.iloc[:,[3,6,5,11]]
    
    # 엑셀 출력
    xw.view(df_종가변동_조인)
    
xw.view(df_베타결과)

+ Recent posts