본문 바로가기
python

Python - BeautifulSoup 객체(ResultSet, Tag) Dict, XML로 변환하기

by 맑은안개 2021. 2. 8.

준비 라이브러리

from bs4 import BeautifulSoup
import json
import xmltodict
  • XML 파싱을 위한 라이브러리 BeautifulSoup

  • JSON 변환용 라이브러리 json

  • XML을 JSON으로 변환 라이브러리 xmltodic

 

XML 파싱

soup = BeautifulSoup('Your xml here', 'xml')

본 블로그에서 사용한 xml 일부

더보기

<data>
<list>
<corp_code>00541349</corp_code>
<corp_name>셀트리온제약</corp_name>
<stock_code>068760</stock_code>
<modify_date>20200225</modify_date>
</list>
<list>
<corp_code>00264255</corp_code>
<corp_name>바텍</corp_name>
<stock_code>043150</stock_code>
<modify_date>20200225</modify_date>
</list>
<list>
<corp_code>00617314</corp_code>
<corp_name>타이거일렉</corp_name>
<stock_code>219130</stock_code>
<modify_date>20200225</modify_date>
</list>
</data>

 

우선 테스트를 위해 한개의 리스트만 find로 조회하면 다음과 같은 결과를 얻는다.

s = soup.find('list')

parsed_dict = xmltodict.parse((str(s)))

json.dumps(parsed_dict)
  • find로 리턴된 s 변수에 담긴 객체는 Tag 객체이다. 리스트의 경우 ResultSet 객체를 리턴한다.

  • dict 로 변환하기 위해 Tag 객체를 문자열로 변환한다.

  • xmltodict.parse를 사용해 변환된 dict 타입의 데이타를 json형태의 문자열로 변환한다

'{"list": {"corp_code": "00434003", "corp_name": "\\ub2e4\\ucf54", "stock_code": null, "modify_date": "20170630"}}'

 

이제 find_all을 사용하여 xml내 모든 'list' 노드를 추출한다.

lists = soup.find_all('list')

 

list내 stock_code 값(text)의 길이가 6자리인 데이타를 필터하여 추출한다. ( Open API 전자공시에서 제공하는 고유번호에는 비상장 업체도 존재하므로 종목코드(stock_code)를 보유한 상장업체만 추출한다. )

result = [x for x in lists if len(x.find('stock_code').get_text()) == 6]

 

리스트 변수 안의 Tag 객체를 꺼내 dict로 변환 후 리스트에 담는다.

data = []
for x in result:
    data.append(xmltodict.parse(str(x))['list'])

 

최종 json 문자열로 변환한다.

json.dumps(data)
.. 생략 ..
{"corp_code": "00519252", "corp_name": "THE E&M", "stock_code": "089230", "modify_date": "20201016"}, {"corp_code": "00961507", "corp_name": "\\uc774\\ub354\\ube14\\uc720\\ucf00\\uc774", "stock_code": "258610", "modify_date": "20201016"}, {"corp_code": "01032404", "corp_name": "\\ucf5c\\ub9c8\\ube44\\uc564\\uc5d0\\uc774\\uce58", "stock_code": "200130", "modify_date": "20201016"}, {"corp_code": "01118281", "corp_name": "\\ud53c\\ud50c\\ubc14\\uc774\\uc624", "stock_code": "304840", "modify_date": "20201019"}, {"corp_code": "00533924", "corp_name": "\\uc561\\ud2b8", "stock_code": "131400", "modify_date": "20201223"}
.. 생략 ..
반응형