HTTP 요청 헤더를 확인해서 API로 사용하기

Alex·2024년 9월 2일

GenAI해커톤

목록 보기
6/9

크롤링 작업을 해보지 않았던 탓에
나는 그전에 작업을 굉장히 비효율적으로 했다.

DART에서 모든 기업 코드를 받아서, 이 기업 코드로 공시정보를 확인하고나서

그걸 기반으로 어떤 보고서가 나오는지 확인한다.
여기서 리포트가 발행된 날짜, 리포트 번호를 다시 크롤링 작업을 통해서 받아와야 했다.

API는 한번정도 쓰이지만 이걸 10만번 해야 했고
여기서 수천개의 기업이 일년에 몇개의 리포트를 공시하니 우리가 필요한 리포트를 걸러내서

이 리포트의 html 응답을 크롤링해서 거기서 dcm_no를 뽑아오고...

너어무 복잡했다.
그래도 ec2 네개를 돌리면서 기업 10만 개를 검색하는 과정을 하루만에 할 수는 있었다.
(여기서 또 DART가 봇으로 의심되는 경우 ip 차단을 피하는 데 많은 시간을 들였다.) 참고

그런데 이번 해커톤에서 우리 팀을 이끄는 리더분께서 DART에서 비상장 기업의 분기 보고서를 찾을 수 있는 검색창이 있다는 이야기를 해주셨다. 이걸 크롤링 할 수는 없겠냐는 것이다...!

그래서 실제로 검색창에 '비상장기업-분기보고서-최근 1년간-최신순으로 정렬- 세부설정을 해놓고 개발자도구를 확인해봤다.

왠지 느낌상 크롤링으로 분기보고서/감사보고서를 가져오는 것을 간단하게 할 수 있을 거 같았다.

여기서 dcm_no(문서 번호), 보고서 제출일자를 알 수 있었기 때문이다.(pdf를 다운로드 하는 url을 만들려면 저 두개의 정보가 필요했다)

포스트맨으로 테스트해보니 실제로 결과가 html으로 잘 왔다...!
유레카!!

private static MultiValueMap<String, Object> buildSearchParameters(int page, String companyName, String reportType) {

        LocalDate endDate = LocalDate.now();
        // 1년 전 날짜 계산
        LocalDate startDate = endDate.minusYears(1);
        // 날짜 포맷 지정 (yyyyMMdd)
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        if (companyName.equals(ALL_COMPANY)) {
            params.add("textCrpNm", "");
            params.add("textCrpNm2", "");
        } else {
            params.add("textCrpNm", companyName);
            params.add("textCrpNm2", companyName);
        }

        params.add("currentPage", page);
        params.add("maxResults", "100");
        params.add("maxLinks", "10");
        params.add("sort", "date");
        params.add("series", "desc");
        params.add("textCrpCik", "");
        params.add("lateKeyword", "");
        params.add("keyword", "");
        params.add("reportNamePopYn", "");
        params.add("textkeyword", "");
        params.add("businessCode", "all");
        params.add("autoSearch", "N");
        params.add("option", "report");
        params.add("reportName", reportType);
        params.add("tocSrch", "");
        params.add("textPresenterNm", "");
        params.add("startDate", startDate.format(formatter));
        params.add("endDate", endDate.format(formatter));
        params.add("decadeType", "");
        params.add("finalReport", "recent");
        params.add("businessNm", "");
        params.add("corporationType", "E");
        params.add("closingAccountsMonth", "all");
        params.add("tocSrch2", "");
        return params;
    }

자바에선 이런식으로 헤더를 만들어주면 됐다.

이번 해커톤을 하면서 도메인 지식을 모르니까 자꾸 헛발질을 한다는 생각이 들었다.

처음에 DART에서 제공하는 API중 무엇을 써야할지? 부터 정하기 어려웠다.
API를 다 호출해야 하나? 분기보고서에는 어떤 정보가 있는지? 감사보고서는 어떻게 다른지? 어떤 형태의 기업(상장, 비상장)이 분기보고서와 감사보고서를 공시하는지? 분기보고서를 공시하는 비상장기업의 매출 규모는 어느정도일지? 수는 얼마나 될지?

이런 것들이 머리속에서 마구 혼재돼서 정리가 안 됐다. 이래서 도메인 지식이 중요하다고 하는 건가보다.

profile
답을 찾기 위해서 노력하는 사람

0개의 댓글