ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python XML Parsing
    ML, DL & Python/Web Parsing 2020. 8. 28. 00:10

    안녕하세요. 오늘은 html소스 코드를 파싱해서 파이썬으로 읽는 것이 아닌, XML형식의 데이터를 파이썬으로 불러와서 처리하는 과정을 알아보려합니다.

     

    XML 관련 라이브러리 xml.etree를 활용하면 되지만 관련 구글링을 진행하고 제 데이터를 파싱해보려고 여러 노력을 했는데 결국은 실패했습니다..

    그래서 저와 같은 분이 또 있을수도 있으니 저희가 소스코드를 파싱할 때 가장 친숙하게 사용하는 requests, BS4를 활용하여 XML데이터를 파싱해보겠습니다.

     

    XML구조는 html구조와는 약간 다르니 이점을 참고해주시면 되겠습니다.

     

    글이 짧은만큼 핵심정보만 제공하니 앞으로 xml데이터를 파싱할 때 이와 같은 방법도 있다라고 생각해주시고 봐주시면 감사하겠습니다.

     

    import requests
    from bs4 import BeautifulSoup
    import re

    먼저 필요한 라이브러리들을 불러옵니다.

     

    예제링크나 파일을 준비하려고 했으나 일단 제가 직접 부딪혔던 문제를 예시로 바로 접근해보겠습니다. 아마도 링크만 다를뿐이지 과정은 똑같을 것이라 생각됩니다.

     

    도서관의 인기도서 리스트를 불러오는 것입니다.

    
    api_key = my_api
    base_url = 'http://data4library.kr/api/loanItemSrch?authKey={}&startDt=2020-01-01&endDt=2020-08-26'
    
    req = requests.get(base_url.format(api_key))
    

     

    데이터는 이런식으로 구조화 되어 있습니다.

    그럼 requests로 get한 데이터를 bs4로 파싱해보겠습니다.

     

    그리고 저희는 경로에서 보시는것처럼 docs의 doc경로에 있는 데이터가 필요하므로 아래와 같이 soup.select를 활용하여 데이터를 불러옵니다.

     

    
    soup = BeautifulSoup(req.content,'html.parser')
    
    book_ls = soup.select('docs > doc')
    

     

    그 다음으로는 doc안에 있는 각 데이터들을 불러오는 것이겠죠?

    각 데이터들도 똑같이 select를 해주시면됩니다.

    
    famous_book = pd.DataFrame()
    
    for idx, book in enumerate(book_ls):
        
        rank = book.select('no')
        name = book.select('bookname')
        author = book.select('authors')
        publisher = book.select('publisher')
        publish_year = book.select('publication_year')
        isbn = book.select('isbn13')
        loan_cnt = book.select('loan_count')
        
        famous_book0 = pd.DataFrame({'rank' : [rank]
                                    ,'name' : [name]
                                    ,'author' : [author]
                                    ,'publisher' : [publisher]
                                    ,'publish_year' : [publish_year]
                                    ,'isbn' : [isbn]
                                    ,'loan_cnt' : [loan_cnt]})
        
        famous_book = famous_book.append(famous_book0)
    

    이렇게 해주시면 아래와 같은 데이터프레임이 만들어집니다.

    데이터 value가 모두 리스트로 감싸져있죠? 제가 한가지 빼먹은게 있습니다.

    기본적으로 xml구조의 데이터가 위와 같이 감싸져있는 형태기 때문에 제가 필요한 것은 텍스트만 필요합니다. 그렇게 때문에 select 뒤에 .text를 붙여서 원하는 데이터만 추출하겠습니다.

     

    
    famous_book = pd.DataFrame()
    
    for idx, book in enumerate(book_ls):
        
        rank = book.select('no')[0].text
        name = book.select('bookname')[0].text
        author = book.select('authors')[0].text
        publisher = book.select('publisher')[0].text
        publish_year = book.select('publication_year')[0].text
        isbn = book.select('isbn13')[0].text
        loan_cnt = book.select('loan_count')[0].text
        
        famous_book0 = pd.DataFrame({'rank' : [rank]
                                    ,'name' : [name]
                                    ,'author' : [author]
                                    ,'publisher' : [publisher]
                                    ,'publish_year' : [publish_year]
                                    ,'isbn' : [isbn]
                                    ,'loan_cnt' : [loan_cnt]})
        
        famous_book = famous_book.append(famous_book0)
    

     

    자 이렇게 추출하면 저희가 원하는 데이터들만 추출할 수 있게됩니다.

     

    앞서 말씀드린것처럼 제가 하는 방식은 xml데이터를 파싱하여 추출하는 방법들 중 이러한 방법도 있다고 알아주시면 되며, xml.etree가 xml데이터를 더 자유자재로 wrangling할 수 있으므로 그 부분에 대해서 공부를 하셔도 좋을 것 같습니다

     

    읽어주셔서 감사합니다.


    댓글

Designed by Tistory.