현재 디렉터리에 있는 PDF에서 첫 페이지만 고화질 이미지로 저장하기

PDF 파일에서 첫 페이지는 보통 표지인데, 표지만 고화질로 저장하고 싶을 때가 있다. PDF 리더의 이미지 내보내기 기능을 이용해 봤는데 화질이 그리 좋지 않기도 하고 파일이 많을 때는 번거로운 작업이기도 하다.

먼저 작업에 PyMuPDF 라이브러리가 필요하므로 아래와 같이 설치한다.

python -m pip install --upgrade pip
python -m pip install --upgrade pymupdf

그러고 나서 아래와 같은 스크립트를 이용하면 glob으로 현재 디렉터리 내 PDF 파일을 모두 나열한 후 파일을 하나씩 열어서 문서의 첫 페지이만 이미지 파일로 저장하는 작업을 수행한다.

import glob, sys, fitz, os

zoom_x = 3.0
zoom_y = 3.0

mat = fitz.Matrix(zoom_x, zoom_y)

path = './'
all_files = glob.glob(path + "*.pdf")

for filename in all_files:
    doc = fitz.open(filename)
    page = doc[0]
    pix = page.get_pixmap(matrix=mat)

    filename_only = os.path.splitext(filename)[0]
    print('Saving cover for {}'.format(filename_only))

    pix.save(filename=f'{filename_only}_cover.png')

참고로 zoom_x, zoom_y의 값을 올려서 확대 배율을 높이면 그만큼 고화질 이미지로 저장된다.

requests에서 GET 요청 시 동일한 이름의 파라미터 전달하기

파이썬 requests 라이브러리를 사용할 때 간혹 요청 대상 사이트의 URL 설계에 따라 같은 이름의 URL 파라미터명을 사용하는 경우가 있다. 즉, 아래와 같은 URL인데, item이라는 이름으로 여러 값을 전달하도록 돼 있는 경우다.

https://example.com?action=buy&item=사과&item=바나나&item=딸기

그런데 무심코 해당 부분을 다음과 같이 뽑아서 요청을 보냈더니 이름이 같아서 값 하나만 전송되는 결과가 발생했다.

data = {
    'action': 'buy',
    'item': '사과',
    'item': '바나나',
    'item': '딸기',
}

resp = session.get(url, params=data)

그래서 구글링해보니 위와 같은 경우에는 다음과 같이 리스트 타입으로 지정하면 처음 의도한 바대로 전송된다.

data = {
    'action': 'buy',
    'item': ['사과', '바나나', '딸기'],
}

resp = session.get(url, params=data)

파이썬에서 CSV 파일을 읽을 때 필드명을 직접 지정하기

파이썬으로 CSV 파일을 읽을 때 헤더 필드명을 직접 정의해서 사용하고 싶을 때가 있다. 이때는 다음과 같이 DictReader 객체를 생성할 때 fieldnames 인수를 직접 지정하면 된다.

with open(filename) as csvfile:
    csv_reader = csv.DictReader(csvfile, fieldnames=['제목', '저자', '페이지수'])

그리고 간혹 텍스트 파일을 읽을 때 \ufeff 문자가 붙어서 읽히는 경우가 있는데, 그럴 때는 다음과 같이 encoding 인수을 지정하는 방식으로 처리하면 된다.

with open(filename, encoding='utf-8-sig') as csvfile:
    csv_reader = csv.reader(csvfile)

\ufeff는 BOM(Bye Order Mark)인데, UTF-8 인코딩의 경우에는 BOM이 필요하지 않다고 한다. 그럼에도 간혹 파일에 포함되는 경우가 있어서 파이썬에서 encoding으로 utf-8-sig를 지정하면 해당 BOM을 무시하게 된다.

참고: python에서 \ufeff가 읽힐 때 해결방법