문서 읽기

Koo·2023년 8월 20일
post-thumbnail
  • Internet은 원래 콘텐츠를 가리지 않고 파일을 전송하는 수단
  • HTML뿐 아니라 텍스트, PDF, 이미지, 비디오, 이메일 등 다양한 정보를 획득 가능
  • 여기서는 문서를 다루는 방법에 대해 공부

문서 인코딩

  • 문서 인코딩은 애플리케이션이 해당 문서를 읽는 방법을 지정
  • 파일 확장자가 반드시 인코딩에 따라 정해지는 것은 아님
    • jpg 파일을 txt로 저장해도 문제가 없음
  • 인코딩 알고리즘은 글자 하나에 몇 비트인지, 이미지 파일이라면 각 픽셀에 몇 비트를 써서 색을 표현할지 등을 정의
  • 알맞은 라이브러리를 사용하면 어떤 형식의 데이터도 다룰 수 있음
  • 인코딩은 파일에 있는 0과 1을 어떻게 해석하는지의 차이만을 나타냄

텍스트

  • 온라인에서는 평범한 텍스트 파일이 많이 사용되지 않음
  • 서비스에 중점을 두지 않는 사이트나 오래된 형식을 따르는 사이트에서 주로 사용됨
  • 텍스트는 parsing할 필요가 없으므로 BeautifulSoup을 사용하지 않아도 됨
from urllib.request import urlopen

textPage = urlopen('http://www.pythonscraping.com/pages/warandpeace/chapter1.txt')
print(textPage.read())

텍스트 인코딩

  • 파일 확장자를 알면 파일을 정확히 알 수 있지만 텍스트 파일에는 적용되지 않음
  • 사이트 소스에 있는 header를 보면 인코딩을 확인할 수 있음

UTF-8(Universal characterset Transformation Format-8bit

  • 8bit를 사용하는 것이 아닌 최소한의 크기를 의미
  • 최대 4byte까지 사용
  • ASCII 앞에 패딩 비트를 추가하여 UTF-8과 ASCII의 인코딩 스키마를 동일하게 맞춤
    • 맨 앞 글자가 0이면 ASCII, UTF-8 모두 읽을 수 있음
    • 맨 앞 글자가 1이면 UTF-8만 읽을 수 있음

ASCII

  • 각 글자에 7비트를 사용
  • 27=1282^7=128글자를 표현 가능

ISO

  • 모든 글자의 첫 비트를 패딩 비트로 만들어 해당 언어에 필요한 특수문자에 사용
  • ISO-8859-9(터키어), ISO-8859-2(독일어), ISO-8859-15(프랑스어) 등 어느 정도 사용되지만 점차 줄어드는 추세

다른 언어 읽기

from urllib.request import urlopen

textPage = urlopen('http://www.pythonscraping.com/pages/warandpeace/chapter1-ru.txt')

print(str(textPage.read(), 'utf-8')) # utf-8을 이용해 문서를 읽으면 정상적으로 읽을 수 있음

BeautifulSoup에서 utf-8 인코딩을 사용하고 싶을 때는 지정해주어야 함

bsObj = BeautifulSoup(html, 'html.parser')
content = bsObj.find('div', {'id': 'mw-content-text'}).get_text()
content = bytes(content, 'utf-8')
content = content.decode('utf-8')

CSV

  • python의 csv 라이브러리는 주로 로컬 파일을 가정하고 만들어짐
  • 원하는 파일을 직접 내려받은 후 python에 파일의 위치를 알려주는 방법
  • 파일을 내려받는 python script를 작성해서 읽는 방법
  • 파일을 문자열 형식으로 읽은 후 StringIO 객체로 바꿔 파일처럼 다루는 방법
    → 하드 디스크에 최대한 저장하지 않고 StringIO 객체로 바꿔 파일처럼 읽는 방법이 가장 효율적
from urllib.request import urlopen
from io import StringIO
import csv

data = urlopen('http://pythonscraping.com/files/MontyPythonAlbums.csv').read().decode(
	'ascii', 'ignore'
)
dataFile = StringIO(data) # StringIO를 사용하지 않으면 한 글자씩 읽게 됨
csvReader = csv.reader(dataFile)

for row in csvReader:
	print(row)

csv.reader를 사용하면 csv 파일의 첫 행까지 한 번에 읽게 된다. csv.DictReader를 사용하면 csv 파일의 첫 행의 field만을 분리 가능

from urllib.request import urlopen
from io import StringIO
from csv import DictReader

data = urlopen('http://pythonscraping.com/files/MontyPythonAlbums.csv').read().decode(
	'ascii', 'ignore'
)
dataFile = StringIO(data)
dictReader = csv.DictReader(dataFile)

print(dictReader.fieldnames)

for row in dictReader:
	print(row)

PDF

  • pdf는 비교적 단순한 오픈 소스 문서 형식으로 python에서 사용 가능한 라이브러리가 많음
  • PDFMiner3k
    • 매우 유연해 명령중에서 사용할 수 있고, 기존 코드에 통합도 가능
    • 다양한 언어 인코딩을 처리 가능
from urllib.request import urlopen
from pdfminer.pdfinterp import PDFResourceManager, process_pdf
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from io import StringIO
from io import open

def readPDF(pdfFile):
	rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, laparams=laparams)
    
    process_pdf(rsrcmgr, device, pdfFile)
    device.close()
    
    content = retstr.getvalue()
    retstr.close()
    
    return content
    
pdfFile = urlopen('http://pythonscraping.com/pages/warandpeace/chapter1.pdf')
outputString = readPDF(pdfFile)
print(outputString)
pdfFile.close()
  • 텍스트로 이루어진 pdf는 대부분 읽을 수 있음
  • 이미가 들어있거나, 텍스트 형식이 이상한 경우, 테이블이나 차트 안에 텍스트가 있는 경우 정상적인 출력이 어려울 수 있음
profile
스터디를 해보자

0개의 댓글