brunch

You can make anything
by writing

C.S.Lewis

by 수민 Apr 30. 2023

다트(DART)로 기업의 성별 임금격차를 구해보자

경향신문 <당신의 회사, 성별 임금격차는?>의 데이터 수집 방법

안녕하세요, 오랜만에 돌아왔습니다. 


3월에 <단지 그대가 여성 노동자라는 이유로> 기획이 나갔습니다. 오늘은 그중 임금격차를 다룬 기사 <당신의 회사, 성별 임금격차는?>에서 사용한 데이터 수집 방법을 소개하려 합니다. 기사는 아래 링크에서 확인하실 수 있습니다.

https://www.khan.co.kr/kh_storytelling/2023/gendergap/view_3.html

 

위 기사는 다트(DART), 알리오(ALIO), 클린아이 등 여러 곳에서 데이터를 받아왔습니다. 알리오는 공공기관, 클린아이는 지방공공기관의 직원 수, 임금, 근속연수 등을 받아볼 수 있는 경영 공시 사이트입니다. 둘은 해당 페이지에서 쉽게 데이터를 받아볼 수 있었습니다. 

다트는 기업 공시 사이트입니다. 기사에 사용한 민간 기업 데이터는 여기서 받아왔습니다. 홈페이지에 검색기가 있어서 기업 이름을 입력하면 해당 기업의 데이터를 조회할 수 있습니다. 하지만 검색할 기업 수가 많을 때는 하나씩 입력해 조회하기가 번거로워 API를 사용합니다. 이번 기획에서는 기업 400여 곳의 직원 수, 임금 등의 정보가 필요해서 API를 사용했습니다. 이때 어떻게 다트 API를 이용해 데이터를 추출했는지, 작업 과정을 공유하고자 합니다.


파이썬을 사용했고 주피터 노트북 환경에서 작업했습니다.



1. API 인증키 받기


API를 사용하려면 인증키가 필요합니다. 인증키를 신청하는 방법은 이렇습니다. OpenDART 페이지에 들어가서 상단 메뉴바의 인증키 신청/관리를 클릭합니다. 여기서 인증키를 신청하시면 됩니다.


신청 후 인증키 관리에 들어가면 인증키 상태를 볼 수 있습니다. '승인'이면 인증키가 발급된 상태입니다. 오픈API 이용현황 탭에 들어가셔서 API Key(인증키)를 받아오면 됩니다. 

이미지 속 덕지덕지 칠해진 부분에 키가 있습니다. 이 친구가 있으면 이제 API를 사용할 수 있습니다.



2. 기업 고유번호 받기


다트 API는 기업의 고유번호를 입력해 해당 기업의 데이터를 요청하는 식으로 사용합니다. 기업 고유번호는 DART에 등록되어 있는 8자리 번호를 말하는데 이것 역시 API를 사용해서 받아야 합니다. 전체 기업의 고유번호를 받는 코드는 아래와 같습니다.


from io import BytesIO
from zipfile import ZipFile
import urllib.request

url = "https://opendart.fss.or.kr/api/corpCode.xml?"
api_key = "인증키"
api_url = url + "crtfc_key=" + api_key

with urllib.request.urlopen(api_url) as zipresponse:
    with ZipFile(BytesIO(zipresponse.read())) as zipfile:
        zipfile.extractall('파일을 저장할 위치')


코드를 실행하면 기업 고유번호 및 이름 등의 정보가 xml 형식으로 받아집니다.

CORPCODE.xml 파일 일부

일부만 가져오면 이런 형태입니다. <list> 태그 안에 각 기업의 고유번호와 이름, 수정 날짜가 들어있습니다. 저는 이것을 좀 더 친근한 dataframe 형태로 바꿔 엑셀로 저장했습니다. 바꿀 때는 xml 파서를 이용하면 됩니다. 코드는 아래와 같습니다.


import pandas as pd
from xml.etree.ElementTree import parse

corp_code, corp_name, stock_code, modify_date = [], [], [], []

tree = parse("CORPCODE.xml")
root = tree.getroot()

company_list = root.findall("list")

for company in company_list:
    corp_code.append(company.find("corp_code").text)
    corp_name.append(company.find("corp_name").text)
    stock_code.append(company.find("stock_code").text)
    modify_date.append(company.find("modify_date").text)

excel = pd.DataFrame({
    '회사코드': corp_code,
    '회사명': corp_name,
    '스톡코드': stock_code,
    '수정일': modify_date
})


회사 이름과 회사의 고유번호를 받았으니 준비가 끝난 셈입니다. 이 고유번호로 기업 데이터를 추출하면 됩니다. 기획에서 직원 수가 1000명 이상인 459개의 민간 기업의 데이터가 필요했는데요. 459개 기업의 이름과 방금 내려받은 파일의 기업 이름을 매칭해 필요한 기업 고유번호를 추출했습니다.



3. 기업의 성별 임금 데이터 추출


기업의 성별 연간 임금 총액, 1인당 평균 임금, 근속 연수 등을 추출하려면 사업보고서의 '직원 현황' 데이터를 요청해야 합니다. 요청 url은 다음과 같습니다.

api_url = "https://opendart.fss.or.kr/api/empSttus.xml?crtfc_key=" + api_key + "&corp_code=" + 기업 고유번호 + "&bsns_year=" + 연도 + "&reprt_code=" + 보고서 코드

api_key는 앞서 선언한 인증키입니다. 위에서 추출한 기업 고유번호를 넣고 원하는 연도를 입력합니다. 보고서 코드는 4가지 보고서 중 하나를 선택하면 됩니다. 4가지는 아래와 같습니다.

1분기, 3분기에는 자세한 직업 현황 데이터가 없을 수 있어서 반기 또는 사업보고서를 호출하는 것이 좋습니다. 연 단위로 보려면 사업보고서를 봐야 합니다.


예를 들어 삼성전자(00126380)의 2023년 사업보고서를 보려면 요청 url은 다음과 같습니다.

api_url = "https://opendart.fss.or.kr/api/empSttus.xml?crtfc_key=" + api_key + "&corp_code=00126380&bsns_year=2023&reprt_code=11011"


이러면 xml 형식으로 삼성전자의 직업 현황이 호출됩니다. 호출된 데이터는 파싱 전엔 뭐가 뭔지 알아보기 힘들 게 생겼습니다. 이럴 땐 API 개발가이드를 참고하면 좋습니다. 저는 먼저 호출된 값을 <list> 단위로 쪼개서 리스트에 넣었습니다. 이러면 삼성전자의 직원 수, 임금, 근속연수가 부문별, 성별로 리스트에 담깁니다. 예를 들어 (리스트명)[0]에 OO부문의 여성 직원 수, 임금, 근속연수가 들어가고 (리스트명)[1]에는 OO부문의 남성 직원 수, 임금, 근속연수가 들어가는 식입니다. 코드는 아래와 같습니다.

from bs4 import BeautifulSoup
import urllib.request

res = requests.get(api_url)
soup = BeautifulSoup(res.text, "lxml")
status = soup.find("status")
if status.text != "000":
    print('error')
else:
    eachCom = soup.find_all('list')

(status "000"은 정상 호출을 의미합니다. 정상적으로 호출되지 않은 경우를 대비해 if문을 넣었습니다.)


습관처럼 beautifulsoup을 불러왔는데 앞서 사용한 xml 파서를 이용해도 될 것 같습니다. <list>로 쪼갠 다음에는 개발가이드에 나와있는 응답키들을 사용해 필요한 데이터를 추출하면 됩니다. 코드 짤 때 사용했던 응답키 딕셔너리를 첨부합니다. 나중에 볼 때 알아보기 좋게 한글 명칭과 연결시켰습니다.

wordDict = {'회사코드': 'corp_code', '회사명': 'corp_name', '사업부문': 'fo_bbm', '성별': 'sexdstn', '정규직': 'rgllbr_co', '계약직': 'cnttk_co', '합계': 'sm', '연간급여총액': 'fyer_salary_totamt', '1인평균급여': 'jan_salary_am', '평균근속연수': 'avrg_cnwk_sdytrn', '접수번호': 'rcept_no'}


응답키를 이용해서 파싱하면 아래와 같이 출력됩니다.

(eachCom은 위에서 <list> 단위로 쪼갠 값을 넣었던 리스트입니다. 이 리스트를 반복문으로 돌려서 응답키에 맞는 값을 불러오고 있습니다.)

위 캡처에는 잘렸지만 삼성전자의 성별합계(사업부문) 1인평균급여도 함께 출력됐습니다. 남성의 1인평균급여는 143,000,000원, 여성은 110,000,000원이었어요. 삼성전자는 여성이 남성의 76.9%만큼 받는다는 사실을 알 수 있었습니다. (기사에 사용된 값과 계산법, 추출 시기 등에 차이가 있어 값이 다를 수 있습니다.)



4. 마치며


다트 오픈 API를 이용해 성별 임금격차 수치를 구하는 방법에 대해 정리해 봤습니다. API가 만능은 아니어서 저렇게 뽑은 후에도 많은 정제가 필요했어요. 성별합계 데이터를 따로 올리지 않은 기업들이 많아서 따로 계산식을 추가해 성별합계를 구해야 했습니다. 쉬운 작업은 아니었지만 그만큼 보람 있었어요.

성별 임금격차는 정말 더디게 개선되고 있는 문제여서 계속 다뤄져야 한다고 생각합니다. 문제를 해결하기 위해선 문제를 분석하는 단계가 필요한데, 이 단계에서 기업의 임금 데이터가 필요합니다. 임금 데이터가 더 투명해지고 접근성이 좋아지면 다양한 방법으로 문제를 분석해 볼 수 있겠죠. 많은 분들이 저희가 제작한 페이지를 통해 임금격차 수치를 쉽게 조회할 수 있으면 좋겠습니다. 그럼 다음 글에서 뵙겠습니다.

작가의 이전글 OO녀를 못 잃는 언론사들에게
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari