프로젝트/관련 스터디

Python으로 PDF 파일 표로 읽고, csv 파일로 변환하기

단ee 2024. 10. 11. 17:57

Tabula 모듈 사용하여 PDF 파일의 표 추출하기


  • PDF로 받은 파일, 특히 표가 들어있는 파일의 데이터를 구글 시트로 옮겨서 사용해야 할 일이 생겼다.
  • 일일이 복붙해서 표로 복원해도 되긴 하는데, 이 파일 같은 경우는 위치가 틀어졌는지 한 번에 옮겨지지 않고 수작업으로 하나씩 고쳐야 했다.
  • 그래서 찾아본, Python을 이용하여 간단하게 해결하는 방법!
  • Docs 링크
  • Tabula-py 모듈 설치가 필요하다. Colab 환경은 코드블럭에서, VS code는 터미널에서 pip install 이용하여 설치. VS code에 모듈 설치는 되는데 실행이 안 돼서 Colab에서 진행.
    • 추측이지만 Windows 10 환경에서는 JAVA 가 설치되어야 실행된다고 하는데, 내 컴퓨터에 JAVA를 따로 설치한 적이 없어서 로컬에서 돌아가지 않았던 것 같다.
  1. Colab 실행 : 아래 명령어를 입력하고 코드를 실행한다.
    !pip install tabula-py

  2. tabula를 불러오고, 변환하려는 파일을 .read_pdf()를 이용해 열어준다. 이 때, 구글 드라이브에 추출하고자 하는 PDF가 있어야 한다.

    • Colab에서 구글 드라이브의 파일을 조작하기 위해서는 구글 드라이브 마운트가 필요하다. 아래 이미지에서 표시한 부분 클릭하여 마운트 진행. 구글 드라이브 경로는 마운트 후 '원하는 파일 우클릭 -> 경로 복사'
    Python 
    import tabula 
    pdf_path = '구글 드라이브 경로' 
    df = tabula.read_pdf(pdf_path, stream=True, pages='all') 
    # pages를 all 로 입력해야 모든 페이지의 표에서 데이터를 추출한다
  3. 이렇게 읽어들인 데이터는 하나의 긴 리스트 안에 저장된다. 처음에는 저 추출 결과가 데이터프레임인 줄 알았으나, df[0], df[1], df[2] 이렇게 각각 리스트에 저장되는 형태. 따라서 pandas의 dataframe에 작동하는 메서드를 바로 쓸 수 없었다.

    Python 
    # 각 페이지의 데이터를 DataFrame으로 변환하여 리스트에 추가 
    df_pages = [] 
    for page_data in df: 
        df_pages.append(pd.DataFrame(page_data)) 
    
    # 모든 페이지의 데이터를 하나의 DataFrame으로 합치기 
    df_combined = pd.concat(df_pages, ignore_index=True) 
    
    # CSV 파일로 출력 
    df_combined.to_csv('/(저장하려는 구글 드라이브 경로)/(저장하려는 CSV 파일명).csv', index=False)
  4. 데이터는 잘 뽑힌다. 다만 위의 방법을 쓸 때, 모든 PDF 페이지에 헤더, 즉 컬럼명이 없다면 1페이지 이후부터는 데이터가 헤더로 쓰이는 문제가 발생한다.

    • 해결을 위해 나는 데이터프레임 변환 전,
      (1) 각각의 컬럼명을 추출해서
      (2) 별도의 데이터프레임으로 저장하고
      (3) 1페이지의 컬럼명으로 일괄 변경한 다음 pd.concat()메서드를 사용해서 컬럼 중복이 되지 않도록 데이터프레임 우선 생성
      (4) 이렇게 생성된 데이터프레임을 2번의 데이터프레임과 한 번 더 concat 해주는 방법으로 데이터 손실을 막았다.
    • 함수를 만든다거나 하는 다른 방법이 있을 것 같긴 한데... csv로 빠르게 뽑고 넘어가는 게 먼저라 그냥 약간의 수작업을 더 했다. 그렇게 해도 일일이 PDF 긁어서 하나씩 고치는 것보단 빨리 끝났다.
  5. 공식 Docs의 다른 메서드 소개

    Python 
    import tabula 
    # PDF 파일을 DataFrame의 리스트로 읽기 
    dfs = tabula.read_pdf("test.pdf", pages='all') 
    
    # PDF 파일을 csv 파일로 바로 변환하기 
    tabula.convert_into("test.pdf", "output.csv", output_format="csv", pages='all') 
    
    # 디렉토리의 모든 PDF 파일 csv 로 변환하기 
    tabula.convert_into_by_batch("input_directory", output_format='csv', pages='all')