Python 30์ผ๐Ÿ‘จโ€๐Ÿ’ป - 21์ผ์ฐจ - ์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋ฐ˜

22250 ๋‹จ์–ด
์˜ค๋Š˜ ๋‚˜๋Š” ํŒŒ์ด์ฌ ์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ์ดˆ ์ง€์‹์„ ํƒ์ƒ‰ํ–ˆ๋‹ค.์Šคํฌ๋ฆฝํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ช…๋ น์„ ํฌํ•จํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜๊ณ  ๋ช…๋ น์ค„์ด๋‚˜ ์ƒํ˜ธ์ž‘์šฉ ์…ธ์—์„œ ์‹คํ–‰ํ•˜์—ฌ ์œ ์šฉํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ž๋™ํ™”ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.PDF, ์ด๋ฏธ์ง€, excel, CSV ๋“ฑ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ „์ž๋ฉ”์ผ์„ ๋ณด๋‚ด๋ฉฐ ํŠธ์œ„ํ„ฐ๋ฅผ ๋งŒ๋“œ๋Š” ๋กœ๋ด‡๊ณผ ๋‹ค๋ฅธ ๋งŽ์€ ์ผ๋“ค์„ Python ์Šคํฌ๋ฆฝํŠธ๋กœ ์ž๋™ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ๋“ค์ด ๋งŽ๋‹ค.์ด ๋„์ „์˜ ์ผ๋ถ€๋กœ์„œ ์ €๋Š” ๊ฐ๋ณธ์˜ ๊ธฐ์ดˆ ์ง€์‹์„ ๋ฐฐ์›Œ์„œ ์ด๋Ÿฌํ•œ ๊ฐœ๋…์„ ์ดํ•ดํ•˜๊ณ  ๋ฏธ๋ž˜์— ๋”์šฑ ๊นŠ์ด ์žˆ๋Š” ํƒ์ƒ‰์„ ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.์˜ค๋Š˜์˜ ์ค‘์ ์€ ํŒŒ์ดํ†ค ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€์™€ PDF ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ๋ณธ ๊ธฐ์ˆ ์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

ํ™”์ƒ ์ฒ˜๋ฆฌ


์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ๋Š” ์ด๋ฏธ์ง€๋ฅผ ๊ฐ•ํ™”ํ•˜๊ฑฐ๋‚˜ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€์— ๋Œ€ํ•ด ํŠน์ •ํ•œ ์กฐ์ž‘์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‚˜ ๊ธฐ์ˆ ์ด๋‹ค.Python์—์„œ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์œ ํ–‰ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด
๋ฒ ๊ฐœ - https://pillow.readthedocs.io/en/stable/index.html
  • OpenCV
  • Python ์ด๋ฏธ์ง€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(ํ๊ธฐ)
  • scikit ์ด๋ฏธ์ง€
  • Pillow๋ฅผ ์‚ฌ์šฉํ•ด ๋ดค๋Š”๋ฐ Python Imaging Library(PIL)์˜ ๊ฐˆ๋ผ์ง„ ๋ฒ„์ „์œผ๋กœ ๋” ์ด์ƒ ์œ ์ง€๋ณด์ˆ˜ํ•˜์ง€ ์•Š๊ณ  ์ตœ์‹  ๋ฒ„์ „์˜ Python๋„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.๋”ฐ๋ผ์„œ PIL์— ๋ฒ ๊ฐœ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
    ์„ค์น˜์™€ ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•์€ ๋ฒ ๊ฐœ ๋ฌธ์„œ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.https://pillow.readthedocs.io/en/stable/index.html
    ๋ช…๋ น pip install Pillow์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…๋ น์ค„์„ ์‚ฌ์šฉํ•˜์—ฌ Pillow๋ฅผ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Œ(ํŠน์ • OS ๋ช…๋ น์˜ ๋ฌธ์„œ ๋ณด๊ธฐ)
    ๊ทธ๋ฆผ ์ฒ˜๋ฆฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.์ฒซ ๋ฒˆ์งธ๋Š” ํด๋”์˜ ๋ชจ๋“  JPEG ํ˜•์‹์˜ ์ด๋ฏธ์ง€๋ฅผ PNG ํ˜•์‹์˜ ์ด๋ฏธ์ง€๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ๋‹ค๋ฅธ ํด๋”์— ์ €์žฅํ•˜๋Š” ๊ธฐ๋ณธ ์ด๋ฏธ์ง€ ๋ณ€ํ™˜๊ธฐ์ž…๋‹ˆ๋‹ค.https://unsplash.com์—์„œ JPEG ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜์—ฌ images ํด๋”์— ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.์Šคํฌ๋ฆฝํŠธ๋Š” ๋ชจ๋“  JPEG ์ด๋ฏธ์ง€๋ฅผ ์ฝ๊ณ  PNG๋กœ ๋ณ€ํ™˜ํ•œ ๋‹ค์Œ ์ƒˆ ํด๋” generated์— ๋ฐฐ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    ๋‹ค์Œ์€ image_convertor.py Here is the GitHub repository link for the project.์ด๋ผ๋Š” ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์˜ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.
    ์›๋ณธ ์ด๋ฏธ์ง€์˜ ํฌ๊ธฐ๊ฐ€ ๋งค์šฐ ํฌ๊ธฐ ๋•Œ๋ฌธ์—, ๋‚˜๋Š” ๋จผ์ € ํฌ๊ธฐ๋ฅผ ์ž‘์€ ํฌ๊ธฐ๋กœ ์กฐ์ •ํ•œ ๋‹ค์Œ์— ๊ทธ๊ฒƒ์„ ๋ณ€ํ™˜ํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ์˜ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œ์ผฐ๋‹ค.image_converter.py
    import os
    from PIL import Image
    
    # fetch all the files from the source folder
    dirname = 'images'
    output_dirname = 'generated'
    images_list = os.listdir(dirname)
    
    # check if output folder exits otherwise create it
    if not os.path.exists(output_dirname):
        os.makedirs(output_dirname)
    
    for image in images_list:
        # split the filename to separate the format and name
        name, format = os.path.splitext(image)
    
        original = Image.open(f'{dirname}\{image}')
    
        # resize image to a standard size and to reduce file size
        size = 1000,1000
        # thumbnail maintains aspect ratio
        original.thumbnail(size) 
    
    
        # save image as png format
        original.save(f'{output_dirname}\{name}.png')
    
    ์Šคํฌ๋ฆฝํŠธ๋Š” ํ„ฐ๋ฏธ๋„ python image_converter.py์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ํด๋”์˜ ์ด๋ฏธ์ง€๋ฅผ ์ž๋™์œผ๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    ๋‚ด๊ฐ€ ๋งŒ๋“  ๋‘ ๋ฒˆ์งธ ์Šคํฌ๋ฆฝํŠธ๋Š” ๋ชจ๋“  ๊ทธ๋ฆผ์„ ํ‘๋ฐฑ ๊ทธ๋ฆผ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ๋ณ€ํ™˜๊ธฐ์ž…๋‹ˆ๋‹ค.๋ฒ ๊ฐœ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ทธ๋ฆผ์— ๋งŽ์€ ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ์ด ๊ทธ ์ค‘์˜ ํ•˜๋‚˜์ด๋‹ค.grayscale_converter.py
    import os
    from PIL import Image, ImageFilter
    
    # fetch all the files from the source folder
    dirname = 'images'
    output_dirname = 'greyscale'
    images_list = os.listdir(dirname)
    
    # check if output folder exits otherwise create it
    if not os.path.exists(output_dirname):
        os.makedirs(output_dirname)
    
    for image in images_list:
        # split the filename to separate the format and name
        name, format = os.path.splitext(image)
    
        original = Image.open(f'{dirname}\{image}')
    
        # resize image to a standard size and to reduce file size
        size = 1000, 1000
        # thumbnail maintains aspect ratio
        original.thumbnail(size)
    
        # convert the image to greyscale
        grayscale_image = original.convert('L')  # L mode means greyscale
        grayscale_image.save(f'{output_dirname}\{image}')
    
    ๋งˆ์ง€๋ง‰์œผ๋กœ, ๋‚˜๋Š” ๋ชจ๋“  ์ด๋ฏธ์ง€์— ๋กœ๊ณ ๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.์ด๊ฒƒ์€ ์ด๋ฏธ์ง€๋ฅผ ํ†ตํ•ฉํ•˜๋Š” ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ–ˆ๋‹ค.๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ ๋ฐ˜๋“œ์‹œ ์ด๋ฏธ์ง€ ์‘์šฉ ๋ธŒ๋žœ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ์ด๊ฒƒ์€ ๋งค์šฐ ์œ ์šฉํ•  ๊ฒƒ์ด๋‹ค.๋‚˜๋Š” ํ‘œ์ง€๋ฅผ ํ•˜๋‚˜ ๋‹ฌ์•˜๋‹ค.png ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋ฃจํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.brand_stamp.py
    import os
    from PIL import Image, ImageFilter
    
    # fetch all the files from the source folder
    dirname = 'images'
    output_dirname = 'branded'
    images_list = os.listdir(dirname)
    logo = Image.open('logo.png')
    
    # check if output folder exits otherwise create it
    if not os.path.exists(output_dirname):
        os.makedirs(output_dirname)
    
    for image in images_list:
        # split the filename to separate the format and name
        name, format = os.path.splitext(image)
    
        original = Image.open(f'{dirname}\{image}')
    
        # resize image to a standard size and to reduce file size
        size = 1000, 1000
        # thumbnail maintains aspect ratio
        original.thumbnail(size)
    
        # create a copy of the image
        image_copy = original.copy()
        # obtain the position to place the logo
    
        position = ((image_copy.width - logo.width),
                    (image_copy.height - logo.height))
        # The third parameter makes it transparent
        image_copy.paste(logo, position, logo)
        image_copy.save(f'{output_dirname}\{name}.png')
    
    ๊ทธ๊ฑฐ ์ •๋ง ๋ฉ‹์žˆ๋‹ค!์ด๊ฒƒ์€ ๋‹จ์ง€ ๊ทธ๋ฆผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ‘œ๋ฉด์ผ ๋ฟ์ด๋‹ค.๋‚˜๋Š” ์ด๊ฒƒ์ด ์ข‹์€ ์ถœ๋ฐœ์ ์œผ๋กœ ๋ฏธ๋ž˜์— ํ”„๋กœ์ ํŠธ๋ฅผ ์ฐฝ์„คํ•  ๋•Œ ๋”์šฑ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.
    ๋‹ค์Œ์€ ๋ฉ‹์ง„ ์ž์›๋“ค์ž…๋‹ˆ๋‹ค. ํŒŒ์ดํ†ค์˜ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ์™€ ๊ด€๋ จ์ด ์žˆ๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.
  • https://auth0.com/blog/image-processing-in-python-with-pillow/
  • https://opensource.com/article/19/3/python-image-manipulation-tools
  • https://stackabuse.com/introduction-to-image-processing-in-python-with-opencv/
  • https://towardsdatascience.com/image-manipulation-tools-for-python-6eb0908ed61f
  • https://github.com/shekkizh/ImageProcessingProjects
  • PDF ํŒŒ์ผ ์ž‘์—…


    ๊ทธ๋ฆผ์„ ๊ฐ€์ง€๊ณ  ๋…ธ๋Š” ๊ฒƒ ์™ธ์— ๋‚˜๋Š” PDF ํŒŒ์ผ์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ ์šฉ๋ก€๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ PDF ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ์ดˆ ์ง€์‹์„ ํƒ์ƒ‰ํ–ˆ๋‹ค.PDF๋Š” ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๊ด‘๋ฒ”์œ„ํ•œ ํŒŒ์ผ ํ˜•์‹ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.
    ์ œ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” PyPDF2 https://pypi.org/project/PyPDF2/์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ œ๊ฐ€ PyPI์—์„œ ์ฐพ์€ ๋งค์šฐ ์œ ํ–‰ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.pip ๋ช…๋ น pip install PyPDF2์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅ
    PDF ๋””๋ ‰ํ† ๋ฆฌ์— ์˜ˆ์ œ PDF ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
    ๋‚ด๊ฐ€ ๋งŒ๋“  ์ฒซ ๋ฒˆ์งธ ์Šคํฌ๋ฆฝํŠธ๋Š” ์ฃผ๋กœ PDF ํŒŒ์ผ์—์„œ ์ž‘์„ฑ์ž, ํŽ˜์ด์ง€ ์ˆ˜, ์ฃผ์ œ, ์ œ๋ชฉ ๋“ฑ์˜ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.info_extractor.py
    from PyPDF2 import PdfFileReader
    
    def extract_information(pdf_path):
        with open(pdf_path, 'rb') as f:
            pdf = PdfFileReader(f)
            information = pdf.getDocumentInfo()
            number_of_pages = pdf.getNumPages()
    
        txt = f"""
        Information about {pdf_path}: 
    
        Author: {information.author}
        Creator: {information.creator}
        Producer: {information.producer}
        Subject: {information.subject}
        Title: {information.title}
        Number of pages: {number_of_pages}
        """
    
        print(txt)
        return information
    
    if __name__ == '__main__':
        path = 'pdfs/sample1.pdf'
        extract_information(path)
    
    python info_extractor.py์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.PDF ํŒŒ์ผ์— ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์ธ์‡„ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ธŒ๋žœ๋“œ ID๋ฅผ ๋ชจ๋“  PDF์— ์›Œํ„ฐ๋งˆํฌ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.์ด๋ฅผ ์œ„ํ•ด ์›Œํ„ฐ๋งˆํฌ๊ฐ€ ์žˆ๋Š” ๋กœ๊ณ ๋งŒ ์žˆ๋Š” ๋‹ค๋ฅธ ๋นˆ PDF๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.์ด์ œ PDF ํŒŒ์ผ๊ณผ ๋ณ‘ํ•ฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.์›Œํ„ฐ๋งˆํฌ๊ฐ€ ์žˆ๋Š” PDF๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ๋งค์šฐ ํ”ํ•œ ์š”๊ตฌ์ด๋ฉฐ, ์ด ์ž‘์—…์„ ์ž๋™ํ™”ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์œ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.pdf_watermarker.py
    from PyPDF2 import PdfFileWriter, PdfFileReader
    
    def create_watermark(input_pdf, output, watermark):
        watermark_obj = PdfFileReader(watermark)
        watermark_page = watermark_obj.getPage(0)
    
        pdf_reader = PdfFileReader(input_pdf)
        pdf_writer = PdfFileWriter()
    
        # Watermark all the pages
        for page in range(pdf_reader.getNumPages()):
            page = pdf_reader.getPage(page)
            page.mergePage(watermark_page)
            pdf_writer.addPage(page)
    
        with open(output, 'wb') as out:
            pdf_writer.write(out)
    
    if __name__ == '__main__':
        create_watermark(
            input_pdf='pdfs/sample1.pdf', 
            output='pdfs/watermarked_sample.pdf',
            watermark='pdfs/watermark.pdf')
    
    python pdf_watermarker.py์„ ์‹คํ–‰ํ•  ๋•Œ๋Š” ์›Œํ„ฐ๋งˆํฌ๊ฐ€ ์žˆ๋Š” PDF ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    PDF๋กœ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์ด ๋งŽ์Šต๋‹ˆ๋‹ค.๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๋‹จ์ง€ ๊ธฐ์ดˆ ์ง€์‹์„ ํ†ตํ•ด ์ด ๊ณผ์ •์„ ์ตํžˆ๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค.๋‚˜๋Š” PDF ์ฒ˜๋ฆฌ๋ฅผ ๊นŠ์ด ์—ฐ๊ตฌํ•˜๊ธฐ ์œ„ํ•ด ํ›Œ๋ฅญํ•œ ์ž์›์„ ์—ฐ๊ฒฐํ•˜๊ณ  ์žˆ๋‹ค.
    ๋‹ค์Œ์€ ํŒŒ์ดํ†ค์—์„œ PDF๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ฐธ๊ณ  ์ž๋ฃŒ๋“ค์ž…๋‹ˆ๋‹ค.
  • https://realpython.com/pdf-python/
  • https://towardsdatascience.com/pdf-preprocessing-with-python-19829752af9f
  • https://www.geeksforgeeks.org/working-with-pdf-files-in-python/
  • https://automatetheboringstuff.com/chapter13/
  • https://medium.com/@umerfarooq_26378/python-for-pdf-ef0fac2808b0
  • ๋ชจ๋“  ๊ด€๋ จ ์ฝ”๋“œ๋Š” Github repo์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ์˜ค๋Š˜์€ ์—ฌ๊ธฐ๊นŒ์ง€.๋‚ด์ผ์€ ํŠธ์œ„ํ„ฐ๋ฅผ ์œ„ํ•œ ์ž๋™ ๋กœ๋ด‡ ๊ตฌ์ถ•, ์ด๋ฉ”์ผ ๋ฐœ์†ก ๋“ฑ ์Šคํฌ๋ฆฝํŠธ์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ๋‚ด์šฉ์„ ํƒ์ƒ‰ํ•  ๊ฒƒ์ด๋‹ค.
    ์ฆ๊ฑฐ์šด ์‹œ๊ฐ„ ๋ณด๋‚ด์„ธ์š”!

    ์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ