정보마당

파이썬으로 xml 데이터 날짜로 소팅하는 방법

IT(Idea Technology) 흑기사 2024. 10. 15. 15:50

파이썬으로 xml 데이터를 처리하다보면 정렬을 좀 하고 싶다라는 생각이 들 수 있습니다. 전 xml 데이터를 조회후 업무상 날짜별로 해서 데이터를 가져와야 한적이 있는데 처음에는 루프로 돌릴까하다가 파이썬인데 고급 기술이 있지 않을까 생각이들었답니다. 그게 beautifulsoup을 이용해 데이터를 가져오고 파이썬 sort를 이용해서 원하는 방법으로 정렬을 하는것입니다.

파이썬으로 xml 데이터 날짜로 소팅하는 방법

 

*먼저 beautifulsoup과 sort의 기본 사용법은 아래를 통해서 확인이 가능합니다.

 

 

👉BeautifulSoup 기본 사용법

 

👉sort 기본 사용법

 

먼저 지금 풀어야 하는 데이터의 형식을 알아보도록 하겠습니다. 보이는것처럼 10월11일,21일,31일 작성한 데이터가 있는데 이 글을 날짜별로 해서 내림차순 혹은 오름차순으로 글을 정렬해 보고자 하는것 입니다.

 

파이썬 데이터

 

도식적으로 표시해 보자면 아래와 같이 날짜가 지금은 21일과 그다음 11일 그리고 31일로 해서 데이터가 나오는데 이걸 날짜를 기준으로 내림차순과 오름차순으로 데이터를 출력하는것 입니다.

 

올림차순, 내림차순

 

 

 

자 이제 파이썬으로 시작해 보시죠!!!

 
  soup = BeautifulSoup(xmlData, 'xml')
 
  urlData = soup.select('url')
 

 

위의 데이터를 먼저 xml 형식으로 불러오고 url이 반복적으로 되어있다보니 soup.select로 다건조회후 List형식으로 저장합니다.

 

그리고 이 데이터를 sorted를 통해서 정렬를 할 것입니다. 이때 reverse 인자값이 내림차순과 오름차순을 구분짓게 되는데 간단하게 설명하면 다음과 같습니다.reverse 설정을 안했을 때 default값은 False입니다.

 

reverse=True를 사용하면 값이 내림차순 정렬됩니다. 

=>(값이 큰 순서부터 ex : 5 > 4 > 3 > 2 > 1 순서로 정렬)

reverse=False 를 사용하면 값이 오름차순정렬됩니다.

=>(값이 작은 순서부터 ex : 1 > 2 > 3 > 4 > 5 순서로 정렬)

 

sort와 sorted와의 차이점도 잠깐 한번 인지하고 진행하겠습니다.

 List에서.sort()와 sorted(리스트)의 두드려진 차이점은
그냥 단순하게 sort() 는 본체의 리스트를 정렬해서 변환하는 것이고,
sorted(리스트) 는 본체 리스트는 내버려두고, 정렬한 새로운 리스트를 반환하는 것입니다.

 

 

다음은 날짜를 파싱하는 부분입니다. string 데이터를 가지고 dateutil.parser를 이용해 날짜형식으로 인식하고 원하는 날짜 포멧으로 변경하면 날짜형식의 데이터로 출력할 수 있습니다.

 

 
 from dateutil.parser import parse as dateParse
 
 publishDate="2024-10-11T15:20:20+09:00" 
 
 publishDate1 = dateParse(publishDate)
 
 publishDate2 = publishDate1.strftime("%Y년 %m월 %d일 %H시 %M분")
 
 print(publishDate2)
 
 >>> 출력결과: 2024년 10월 11일 15시 20분 으로 출력됨
 

 

이를 이용해 날짜를 소팅해 보겠습니다. 간략하게 보면 위의 날짜형식으로 바꾸는 부분을 람다형식으로 변수 선언을 하면됩니다. 어렵게 생각했는데 그렇게 어렵지 않게 해결을 되더라구요

 

sort 핵심

 

 

 

전체소스를 공개합니다. 혹시 궁금한점이나 이해안되는 부분은 댓글 남겨주세요~

from bs4 import BeautifulSoup
from dateutil.parser import parse as dateParse
from datetime import datetime
from datetime import datetime, timedelta
import re
from datetime import datetime, date
import json

xmlData = """<root>
  <url>
    <title>나라</title>
    <loc>https://aaa.com/200</loc>
    <lastmod>2024-10-21T16:41:34+29:00</lastmod>
  </url>
  <url>
    <title>만세</title>
    <loc>https://aaa.com/100</loc>
    <lastmod>2024-10-11T15:20:20+09:00</lastmod>
  </url>
  <url>
    <title>우리</title>
    <loc>https://aaa.com/300</loc>
    <lastmod>2024-10-31T12:18:44+09:00</lastmod>
  </url>
 
</root>"""

soup = BeautifulSoup(xmlData, 'xml')
urlData = soup.select('url')

dateListAsc = sorted(soup.select('url'), key=lambda x: datetime.strftime(dateParse(x.select_one('lastmod').text), '%Y%m%d%H%M'))
dateListDesc = sorted(soup.select('url'), key=lambda x: datetime.strftime(dateParse(x.select_one('lastmod').text), '%Y%m%d%H%M'),reverse=True)



#원본 리스트
dataList=[]

#날짜 리스트
dateDataListAsc=[]
dateDataListDesc=[]

#print("########### 원본 #################")
for item in urlData:
    title = item.select_one('title').text
    link = item.select_one('loc').text
    updated1 = item.select_one('lastmod').text
    updated2 = dateParse(updated1)
    updated = updated2.strftime("%Y년 %m월 %d일 %H시 %M분")
    infoData={}
    infoData['title']=title
    infoData['link']=link
    infoData['updated']=updated
    dataList.append(infoData)

#print("########### 날짜로 오름차순 시작 #################")
for item in dateListAsc:
    title = item.select_one('title').text
    link = item.select_one('loc').text
    updated1 = item.select_one('lastmod').text
    updated2 = dateParse(updated1)
    updated = updated2.strftime("%Y년 %m월 %d일 %H시 %M분")
    infoData={}
    infoData['title']=title
    infoData['link']=link
    infoData['updated']=updated
    dateDataListAsc.append(infoData)

for item in dateListDesc:
    title = item.select_one('title').text
    link = item.select_one('loc').text
    updated1 = item.select_one('lastmod').text
    updated2 = dateParse(updated1)
    updated = updated2.strftime("%Y년 %m월 %d일 %H시 %M분")
    infoData={}
    infoData['title']=title
    infoData['link']=link
    infoData['updated']=updated
    dateDataListDesc.append(infoData)
print('\n')
print("########### 원본 #################")
for info in dataList:
    print("title:"+info['title']+",link:"+info['link']+", updated:"+info['updated']) 

print('\n')

print("########### date로 오름차순 #################")
for info in dateDataListAsc:
    print("title:"+info['title']+",link:"+info['link']+", updated:"+info['updated'])  
print('\n')
print("########### date로 내림차순 #################")
for info in dateDataListDesc:
    print("title:"+info['title']+",link:"+info['link']+", updated:"+info['updated'])