728x90

하나의 글에서 여러문자를 반복해서 바꾸고 싶은데 한번씩 바꾸기 너무 귀찮아서 그냥 만들어버린 프로그램
초보자 답게 예쁘게 다듬는건 없음

결과를 먼저 보면

변경전
바꾸기를 이용해서 한번에 모든 문자열 변경

from tkinter import *
from tkinter import filedialog
from tkinter import messagebox


class Notepad:
    def __init__(self,window):
        # 창 생성
        self.text = Text(window, height=30, width=80)
        self.text.pack()
        window.title("문자열 변경 노트패트")

        # 메뉴를 붙인다
        menu = Menu(window)
        window.config(menu=menu)

        filemenu = Menu(menu)
        menu.add_cascade(label="파일", menu=filemenu)
        filemenu.add_command(label="열기", command=open)
        filemenu.add_command(label="저장하기", command=self.save)
        filemenu.add_command(label="종료", command=exit)

        changemenu = Menu(menu, tearoff=0)  
        menu.add_cascade(label="바꾸기", menu=changemenu)
        changemenu.add_command(label="문자변경프로그램", command=self.change_window)


    def open(self):
        # 파일 대화창을 askopenfile을 이용해서 만들고, 동시에 읽는다
        file = filedialog.askopenfile(parent=self.window, mode='r')
        if file != None:
            lines = file.read()
            # 1.0은 line.column이다.
            # line은 1부터 시작하고 column은 0부터 시작함..
            self.text.insert('1.0', lines)
            file.close()

    def save(self):
        # 쓰고 저장하는 기능
        file = filedialog.asksaveasfile(parent=self.window, mode='w')
        if file != None:
            lines = self.text.get('1.0', END + '-1c')  # 마지막에서 1 char 뺀다, \n제거!
            file.write(lines)
            file.close()

    def exit(self):
        if messagebox.askokcancel("Quit", "종료하시겠습니까?"):
            self.window.destroy()

    def change_window(self):
        window2 = Tk()
        window2.geometry('250x250')
        window2.title("문자열 변경")
        label1 = Label(window2, text="변경 전", bg="light green")
        label1.grid(row=0, column=1)
        self.bf1 = Entry(window2, width=10)
        self.bf1.grid(row=1, column=1)
        self.bf2 = Entry(window2, width=10)
        self.bf2.grid(row=2, column=1)
        self.bf3 = Entry(window2, width=10)
        self.bf3.grid(row=3, column=1)
        self.bf4 = Entry(window2, width=10)
        self.bf4.grid(row=4, column=1)
        self.bf5 = Entry(window2, width=10)
        self.bf5.grid(row=5, column=1)
        self.bf6 = Entry(window2, width=10)
        self.bf6.grid(row=6, column=1)
        self.bf7 = Entry(window2, width=10)
        self.bf7.grid(row=7, column=1)
        self.bf8 = Entry(window2, width=10)
        self.bf8.grid(row=8, column=1)
        self.bf9 = Entry(window2, width=10)
        self.bf9.grid(row=9, column=1)
        self.bf10 = Entry(window2, width=10)
        self.bf10.grid(row=10, column=1)
        label2 = Label(window2, text="변경 후", bg="light blue")
        label2.grid(row=0, column=3)
        self.af1 = Entry(window2, width=10)
        self.af1.grid(row=1, column=3)
        self.af2 = Entry(window2, width=10)
        self.af2.grid(row=2, column=3)
        self.af3 = Entry(window2, width=10)
        self.af3.grid(row=3, column=3)
        self.af4 = Entry(window2, width=10)
        self.af4.grid(row=4, column=3)
        self.af5 = Entry(window2, width=10)
        self.af5.grid(row=5, column=3)
        self.af6 = Entry(window2, width=10)
        self.af6.grid(row=6, column=3)
        self.af7 = Entry(window2, width=10)
        self.af7.grid(row=7, column=3)
        self.af8 = Entry(window2, width=10)
        self.af8.grid(row=8, column=3)
        self.af9 = Entry(window2, width=10)
        self.af9.grid(row=9, column=3)
        self.af10 = Entry(window2, width=10)
        self.af10.grid(row=10, column=3)

        button = Button(window2, text="클   릭", bg="darkorchid", command=self.change_word)
        button.grid(row=12, column=2)

    def change_word(self):
        find_str=[self.bf1.get(),self.bf2.get(),self.bf3.get(),self.bf4.get(),self.bf5.get(),self.bf6.get(),self.bf7.get(),self.bf8.get(),self.bf9.get(),self.bf10.get()]
        replace_str=[self.af1.get(),self.af2.get(),self.af3.get(),self.af4.get(),self.af5.get(),self.af6.get(),self.af7.get(),self.af8.get(),self.af9.get(),self.af10.get()]

        for i in range(len(find_str)):
            if find_str[i] and replace_str[i]:
                content = self.text.get(1.0, END)
                new_content = content.replace(find_str[i], replace_str[i])
                self.text.delete(1.0, END)
                self.text.insert(END, new_content)


if __name__ == "__main__":
    window = Tk()
    notepad = Notepad(window)
    window.mainloop()

 

728x90
728x90
import pandas as pd
import openpyxl
import xlrd
import re

pd.set_option('display.max_columns',None)
pd.set_option('display.max_rows',None)
728x90
728x90

관세청에서 확인할 내용

개발자 모드 Network에서 retrieveTradeRegion.do 확인
Header에서 general, header등 확인.

중요한건 payload : 검색날짜, 시도 코드, HS코드 길이, HS코드 등 중요

파이썬 코드 작성

def bhi_trade(self): #비에이치아이
    try:
        check_open_file = open("D:\\4.각종INDEX\\★기업별수출입★.xlsx", "+r")
        check_open_file.close()
    except:
        QMessageBox.about(self, "message", "엑셀 close!!")
        return 0
    strdate = self.dateEdit_str.date() #.toString("yyyyMM")
    enddate = self.dateEdit_end.date() #.toString("yyyyMM")

    sido = ['48']  # 경상남도
    sgg =  ['637'] # 함안
    hscode = ['84']  # 라면
    self.ret_value = self.tradeWeb.get_tradeDataWeb(strdate, enddate, sido,sgg,hscode)

    self.error_message("비에이치아이", self.ret_value)
    pass
class TradedataWebPage():
    def __init__(self):
        self.url = 'http://apis.data.go.kr/1220000/sidoitemtrade/getSidoitemtradeList'
        self.strYYmm = {}
        self.endYYmm = {}
        self.sido = {}
        self.sgg = {}
        self.strHS_NumOfDigit = {}
        self.hashcode = {}
        self.url_tradedata_go_kr = 'https://tradedata.go.kr/cts/hmpg/retrieveTradeRegion.do'  # 지역별-품목별-수출입실적(시군구)
        self.headers = {  # 만질필요없는듯
            'Accept': 'application/json, text/javascript, */*; q=0.01',
            'Accept-Encoding': 'gzip, deflate, br',
            'Accept-Language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Host': 'tradedata.go.kr',
            'isAjax': 'true',
            'Origin': 'https://tradedata.go.kr',
            'Referer': 'https://tradedata.go.kr/cts/index.do',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.104 Whale/3.13.131.36 Safari/537.36',
            'X-Requested-With': 'XMLHttpRequest',
        }
        self.params = {
            'tradeKind': 'ETS_MNK_1040000A',
            'sidosggKind': 'sgg',
            'priodKind': 'MON',
            'priodFr': f'{self.strYYmm}',
            'priodTo': f'{self.endYYmm}',
            'statsBase': 'acptDd',
            'sidoCd': f'{self.sido}', #도
            'sggCd': f'{self.sgg}', #시군군구
            'imexTpcd': 'EXP_TMPR_CD',
            'showPagingLine': '15',
            'sortColumn': '',
            'sortOrder': '',
            'hsSgnGrpCol': f'{self.strHS_NumOfDigit}', #HS4_SGN HS코드자리수 ex) 19(곡물),1902(파스타),190230(그밖의파스타) //6자리까지
            'hsSgnWhrCol': f'{self.strHS_NumOfDigit}',
            'hsSgn': f'{self.hashcode}',  #
        }
def get_tradeDataWeb(self,strdate,enddate,sido,sgg,hscode):
    strdate = strdate.toString("yyyyMM")
    enddate = enddate.toString("yyyyMM")

    self.df_tradeData = []
    df_hs = pd.DataFrame()

    for hs in range(len(hscode)):
        hsnum = 'HS' + str(len(hscode[hs])) + '_SGN'  # HS4_SGN, HS6_SGN
        df_sido = pd.DataFrame()
        for si in range(len(sido)):
            self.params.update({'priodFr':strdate, 'priodTo':enddate, 'sidoCd':sido[si], 'sggCd':sgg[si],'hsSgnGrpCol':hsnum,'hsSgnWhrCol':hsnum,'hsSgn':hscode[hs]})
            self.df_tradeData = self.sub_get_tradeDataWeb()
            df_sido = df_sido._append(self.df_tradeData)
        df_hs = df_hs._append(df_sido)
def sub_get_tradeDataWeb(self):
    res = requests.post(self.url_tradedata_go_kr, headers=self.headers, params=self.params)
    data = json.loads(res.text)
728x90
728x90

ex) 삼양식품 - 라면 - 강원도(원주), 경상남도(밀양), 전라남도(익산) 수출건수,수출금액 가져오기

main 함수

# 0.기업별
def samyang_trade(self):
    strdate = self.dateEdit_str.date() #.toString("yyyyMM")
    enddate = self.dateEdit_end.date() #.toString("yyyyMM")
    sido = ['51','48','45'] #강원도,경상남도,전라북도
    hscode = ['1902301010'] #라면

    self.ret_value = self.trade.get_tradeData(strdate,enddate,sido,hscode)
    if self.ret_value == 101:
        QMessageBox.about(self, "message", "시작과 종료의 조회기간은 1년이내 기간만 가능합니다.")
        return 0
    QMessageBox.about(self, "message", "삼양식품 크롤링 완료")
    pass
  • 데이터를 수집할 월 을 가져오기 
  • API는 합계 데이터 (ex.1~3월 합계 수출건수, 수출금액)을 가져와서 매 달 건수,금액 가져오는 코드 필요
  • 조회기간은 1년이내만 가능
  • 총 조회가능 건수는 100건.

class 만들기

class Tradedata():
    def __init__(self):
        api_key = '---개인별 key----'
        self.url = 'http://apis.data.go.kr/1220000/sidoitemtrade/getSidoitemtradeList'
        self.strYYmm = {}
        self.endYYmm = {}
        self.sido = {}
        self.hashcode = {}
        self.params = {
            'serviceKey': api_key,
            'strtYymm': f'{self.strYYmm}',
            'endYymm': f'{self.endYYmm}',
            'sidoCd': f'{self.sido}',
            'hsSgn': f'{self.hashcode}',
            }
        pass
  • init 준비
def get_tradeData(self,strdate,enddate,sido,hscode):
    # 매월 돌려야하므로 기간 내 해당하는 월을 추출
    i=0
    priodMonth = []
    while True:
        p_date= enddate.addMonths(-i)
        i = i + 1
        a=p_date.toString("yyyyMM")
        priodMonth.append(a)
        b=strdate.toString("yyyyMM")
        re = int(a) - int(b)
        if re == 0:
            break
    if len(priodMonth) > 12 :
        return 101 #기간이 1년 넘습니다.
    priodMonth.reverse()
  • 가저온 시작/마지막 날짜 데이터 (2023-01-01)을 202301로 바꾸어줌.
  • 12개월은 넘기면 안되므로 예외값 처리
  • priodMonth 리스트에 시작~마지막 달까지 데이터 삽입 -> 결과: [202309,202308,202307]
  • priodMonth 과거 데이터 부터 조회하기 위해 reverse  -> 결과: [202307,202308,202309]
self.df_tradeData = []
df_hs = pd.DataFrame()
for hs in range(len(hscode)):
    df_sido = pd.DataFrame()
    for si in range(len(sido)):
        # 각 월 수출량
        df_mon = pd.DataFrame(index=['기간', '수출건수', '수출금액'])
        for mon in range(len(priodMonth)):
            self.params.update({'strtYymm': priodMonth[mon], 'endYymm': priodMonth[mon], 'sidoCd': sido[si], 'hsSgn': hscode[hs]})
            self.df_tradeData = self.sub_get_tradeData(priodMonth[mon])
            df_mon[len(df_mon.columns)]=self.df_tradeData
        df_sido = df_sido._append(df_mon)
    df_hs=df_hs._append(df_sido)
  • 각 params 를 이용하여 데이터를 가져옴
  • 달, 시도, 해시코드별 for문 돌아서 원하는 데이터 가져오기
def sub_get_tradeData(self, priodMonth):
    res = requests.get(self.url, params=self.params, headers={"user-agent": user_agent}, verify=False)
    data = xmltodict.parse(res.content.decode('utf-8'))
    if data['response']['body']['items'] == None: #데이터가 없는경우 0으로 예외처리
        none_df = pd.DataFrame([[priodMonth, '0', '0']], columns=['기간', '수출건수', '수출금액'])
        none_df = none_df.transpose()
        return none_df
    sub_df = pd.DataFrame(data['response']['body']['items']['item'])
    #가져온 데이터 프레임에서 수출건수와 수출금액만을 가져와서 깔끔하게 정렬하기
    sub_df =sub_df[['expLnCnt', 'expUsdAmt']]  # hsSgn에서 상세 내역 추출
    sub_df.columns = ['수출건수', '수출금액']
    sub_df[['수출건수', '수출금액']] = sub_df[['수출건수', '수출금액']].apply(
        lambda x: x.str.replace('[\s,]', '', regex=True)).astype(int)
    sub_df = sub_df.transpose() #데이터 프레임의 행과 열을 바꿈
    col_list = list(sub_df.columns)
    for i in range(len(sub_df.columns)):
        col_list[i] = i
    sub_df.columns = col_list

    #  cmtrBlncAmt expLnCnt expUsdAmt impLnCnt impUsdAmt priodTitle   hsSgn     korePrlstNm
    #0      46,403    2,052    46,467    2,751        63         총계     NaN      NaN
    #1      46,403    1,052    46,467    2,751        63       2023  190230      그 밖의 파스타
    sub_df = sub_df.drop(1,axis='columns') #결과가 위와 같으니 하나만 가져옴. 어차피 한달내용만 필요.

    add_priod_df = pd.DataFrame([[priodMonth]], index=['기간'], columns=sub_df.columns)
    sub_df= pd.concat([sub_df.iloc[:0], add_priod_df, sub_df.iloc[0:]]) # 첫행에 날짜 추가

    # sub_df 결과값
    # 기간    202301
    # 수출건수     384
    # 수출금액   15249
    return sub_df
  • 가장최근달은 데이터가 없을수도 있으므로 0으로 하나의 데이터 프레임 생성.
  • 필요한 수출건수 수출내용만 추출

 

728x90

+ Recent posts