วิธีการแยกข้อความจากไฟล์ PDF?


190

ฉันพยายามที่จะดึงข้อความที่รวมอยู่ในนี้ไฟล์ PDF Pythonที่ใช้

ฉันใช้โมดูลPyPDF2และมีสคริปต์ต่อไปนี้:

import PyPDF2
pdf_file = open('sample.pdf')
read_pdf = PyPDF2.PdfFileReader(pdf_file)
number_of_pages = read_pdf.getNumPages()
page = read_pdf.getPage(0)
page_content = page.extractText()
print page_content

เมื่อฉันเรียกใช้รหัสฉันได้รับผลลัพธ์ต่อไปนี้ซึ่งแตกต่างจากที่รวมอยู่ในเอกสาร PDF:

!"#$%#$%&%$&'()*%+,-%./01'*23%4
5'%1$#26%3/%7/))/8%&)/26%8#3"%3"*%313/9#&)
%

ฉันจะแยกข้อความตามที่อยู่ในเอกสาร PDF ได้อย่างไร


9
ฉันไม่เคยใช้โมดูลที่ แต่ไม่ได้สร้างความแตกต่างถ้าคุณเปิดไฟล์ในโหมดไบนารี: pdf_file = open('sample.pdf', 'rb')?
PM 2Ring

2
ขอบคุณสำหรับการตอบกลับของคุณ. ฉันลองมันด้วยโหมดไบนารี แต่ไม่มีอะไรเปลี่ยนแปลง
Simplicity

3
คัดลอกข้อความโดยใช้โปรแกรมดู PDF ที่ดี - Acrobat Reader ที่เป็นที่ยอมรับของ Adobe ถ้าเป็นไปได้ คุณได้รับผลลัพธ์เดียวกันหรือไม่ ความแตกต่างไม่ใช่ว่าข้อความจะแตกต่างกัน แต่ตัวอักษรคือ - รหัสตัวละครแมปกับค่าอื่น ๆ PDF บางส่วนเท่านั้นที่มีข้อมูลที่ถูกต้องในการกู้คืน
usr2564301

2
รูปแบบไฟล์ PDF ที่มีตัวอักษรตาราง CMap ดังนั้นข้อ จำกัด และการทำงาน arounds กล่าวถึงในหัวข้อนี้มีความเกี่ยวข้อง - stackoverflow.com/questions/4203414/...
dwarring

2
PDF นั้นมี CMAP ที่ถูกต้องดังนั้นจึงเป็นการง่ายที่จะแปลงการแมปอักขระ ad hoc เป็นข้อความธรรมดา อย่างไรก็ตามต้องใช้การประมวลผลเพิ่มเติมเพื่อดึงลำดับของข้อความที่ถูกต้อง ตัวแสดงควอตซ์ PDF ของ Mac OS X เป็นงานที่น่ารังเกียจ! ในลำดับการเรนเดอร์ดั้งเดิมฉันได้รับ "m T'h iuss iisn ga tosam fopllloew DalFo dnogc wumithe ntht eI กวดวิชา" ... หลังจากจัดเรียงตามพิกัด x ฉันได้รับผลลัพธ์ที่ถูกต้องมากกว่า: "นี่คือตัวอย่างเอกสาร PDF ฉัน ใช้เพื่อติดตามพร้อมกับบทช่วยสอน "
usr2564301

คำตอบ:


200

ฉันกำลังมองหาวิธีแก้ปัญหาอย่างง่ายสำหรับ python 3.x และ windows ดูเหมือนจะไม่ได้รับการสนับสนุนจากtextractซึ่งเป็นเรื่องโชคร้าย แต่ถ้าคุณกำลังมองหาวิธีแก้ปัญหาง่ายๆสำหรับ windows / python 3 ชำระเงินแพ็คเกจtikaตรงไปตรงมาสำหรับการอ่านไฟล์ PDF

Tika-Python เป็น Python ที่เชื่อมโยงกับบริการ Apache Tika ™ REST ซึ่งอนุญาตให้ Tika ถูกเรียกใช้ในชุมชน Python

from tika import parser # pip install tika

raw = parser.from_file('sample.pdf')
print(raw['content'])

โปรดทราบว่า Tika เขียนขึ้นใน Java ดังนั้นคุณจะต้องติดตั้ง Java runtime


17
ฉันทดสอบ pypdf2, tika และพยายามและล้มเหลวในการติดตั้ง textract และ pdftotext Pypdf2 ส่งคืน 99 คำขณะที่ tika ส่งคืนทั้งหมด 858 คำจากใบแจ้งหนี้ทดสอบของฉัน ดังนั้นฉันเลยไปกับ tika
Stian

8
ผู้ชายฉันรักคุณ ฉันไม่รู้ว่าทำไมคำตอบที่ดีนั้นถูกซ่อนอยู่ใน StackOverflow ทุกคนพูดถึงว่าเราจำเป็นต้องใช้ PyPDF2 หรือ pdfminer แต่พวกเขาก็เหม็น ฉันหลงรัก tika แล้ว
jxpython

15
ฉันได้รับข้อผิดพลาด "RuntimeError: ไม่สามารถเริ่มเซิร์ฟเวอร์ Tika" ได้
Nav

3
คำตอบฉันค้นหาตลอดชีวิตแล้วทำไมไม่มีใครแนะนำติก้า? ขอบคุณ!
Jacob-Jan Mosselman

4
หากคุณต้องการเรียกใช้สิ่งนี้กับไฟล์ PDF ทั้งหมดในไดเรกทอรี (เรียกซ้ำ) ให้ใช้สคริปต์นี้
หวังว่า

58

ใช้ textract

รองรับไฟล์หลายประเภทรวมถึง PDF

import textract
text = textract.process("path/to/file.extension")

24
Textwrap ดูเหมือนจะเป็น wrapper ที่ดี แต่อาศัยยูทิลิตี้ที่ไม่ใช่ Python จำนวนมากซึ่งอาจไม่สามารถใช้ได้อย่างง่ายดายบนระบบที่กำหนด
David Brown

1
ใช้งานได้กับ PDF, epubs ฯลฯ - ประมวลผล PDF ที่แม้แต่ PDFMiner ล้มเหลว
Ulad Kasach

วิธีการใช้งานใน aws lambda ฉันลองสิ่งนี้ แต่ข้อผิดพลาดในการนำเข้าเกิดขึ้นจากเท็กซ์เท็กซ์
Arun Kumar

5
textractเป็นเสื้อคลุมสำหรับPoppler:pdftotext(ในหมู่อื่น ๆ )
onewhaleid

1
@ArunKumar: หากต้องการใช้อะไรใน AWS แลมบ์ดาที่ไม่ใช่ในตัวคุณต้องรวมมันและการพึ่งพาพิเศษทั้งหมดไว้ในชุดข้อมูลของคุณ
Jeff Learman

51

ดูรหัสนี้:

import PyPDF2
pdf_file = open('sample.pdf', 'rb')
read_pdf = PyPDF2.PdfFileReader(pdf_file)
number_of_pages = read_pdf.getNumPages()
page = read_pdf.getPage(0)
page_content = page.extractText()
print page_content.encode('utf-8')

ผลลัพธ์คือ:

!"#$%#$%&%$&'()*%+,-%./01'*23%4
5'%1$#26%3/%7/))/8%&)/26%8#3"%3"*%313/9#&)
%

ใช้รหัสเดียวกันในการอ่านไฟล์ PDF จาก 201308FCR.pdf ผลลัพธ์เป็นเรื่องปกติ

ใช้เอกสารอธิบายว่าทำไม:

def extractText(self):
    """
    Locate all text drawing commands, in the order they are provided in the
    content stream, and extract the text.  This works well for some PDF
    files, but poorly for others, depending on the generator used.  This will
    be refined in the future.  Do not rely on the order of text coming out of
    this function, as it will change if this function is made more
    sophisticated.
    :return: a unicode string object.
    """

@VineeshTP: คุณได้รับอะไรกับ page_content หรือไม่ ถ้าใช่ให้ดูว่าช่วยได้หรือไม่โดยใช้การเข้ารหัสที่แตกต่างจาก (utf-8)
Quinn

ห้องสมุดที่ดีที่สุดที่ฉันพบสำหรับการอ่าน pdf โดยใช้ python คือ 'tika'
Vineesh TP

201308FCR.pdf ไม่พบ
Chaitanya Bapat

30

หลังจากลองใช้ textract (ซึ่งดูเหมือนว่ามีการพึ่งพามากเกินไป) และ pypdf2 (ซึ่งไม่สามารถแยกข้อความจากไฟล์ pdf ที่ฉันทดสอบด้วย) และ tika (ซึ่งช้าเกินไป) ฉันลงเอยด้วยการใช้pdftotextxpdf (ตามที่แนะนำแล้วในคำตอบอื่น) และ เพิ่งเรียกไบนารีจาก python โดยตรง (คุณอาจต้องปรับพา ธ ให้เป็น pdftotext):

import os, subprocess
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
args = ["/usr/local/bin/pdftotext",
        '-enc',
        'UTF-8',
        "{}/my-pdf.pdf".format(SCRIPT_DIR),
        '-']
res = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = res.stdout.decode('utf-8')

มีpdftotextซึ่งทำหน้าที่เหมือนกัน แต่ถือว่า pdftotext ใน / usr / local / bin ในขณะที่ฉันใช้สิ่งนี้ในแลมบ์ดา AWS และต้องการใช้จากไดเรกทอรีปัจจุบัน

Btw: สำหรับการใช้สิ่งนี้บนแลมบ์ดาคุณต้องใส่ไบนารี่และการพึ่งพาlibstdc++.soลงไปในฟังก์ชั่นแลมบ์ดาของคุณ ฉันต้องการรวบรวม xpdf เป็นการส่วนตัว ในฐานะที่เป็นคำแนะนำนี้จะระเบิดขึ้นคำตอบนี้ฉันทำให้พวกเขาในบล็อกส่วนตัวของฉัน


4
โอ้พระเจ้ามันใช้งานได้ !! ในที่สุดการแก้ปัญหาที่แยกข้อความในลำดับที่ถูกต้อง! ฉันต้องการกอดคุณสำหรับคำตอบนี้! (หรือถ้าคุณไม่ชอบกอดนี่คือกาแฟเสมือนจริง / เบียร์ / ... )
DonQuiKong

4
ดีใจที่มันช่วย! การ upvoting นั้นให้ความรู้สึกเหมือนกับการกอดดังนั้นฉันสบายดี!
hansaplast

ง่าย ๆ ... gr8 คิดนอกกรอบ!
shantanu pathak

10

คุณอาจต้องการใช้xPDF ที่พิสูจน์แล้วเวลาและเครื่องมือที่ได้รับมาเพื่อแยกข้อความแทนเนื่องจาก pyPDF2 ดูเหมือนจะมีปัญหาต่าง ๆกับการแยกข้อความ

คำตอบยาวคือมีหลายรูปแบบวิธีการเข้ารหัสข้อความใน PDF และมันอาจจำเป็นต้องถอดรหัสสตริง PDF ตัวเองแล้วอาจต้องแมปกับ CMAP แล้วอาจต้องวิเคราะห์ระยะห่างระหว่างคำและตัวอักษร ฯลฯ

ในกรณีที่ไฟล์ PDF เสียหาย (เช่นการแสดงข้อความที่ถูกต้อง แต่เมื่อคัดลอกมันให้ขยะ) และคุณจำเป็นต้องแยกข้อความจริงๆแล้วคุณอาจต้องการพิจารณาแปลง PDF เป็นภาพ (ใช้ImageMagik ) แล้วใช้Tesseractเพื่อรับข้อความจากภาพ ใช้ OCR


-1 เนื่องจาก OP ขอให้อ่านไฟล์ PDF ใน Python และถึงแม้ว่าจะมีตัวห่อ xpdf สำหรับ python มันก็ยังคงไม่ดีพอ
cduguet

9

ฉันลองใช้ตัวแปลง Python PDF จำนวนมากและฉันต้องการอัปเดตรีวิวนี้ Tikaเป็นหนึ่งในดีที่สุด แต่PyMuPDFเป็นข่าวดีจากผู้ใช้ @ehsaneha

ฉันทำโค้ดเพื่อเปรียบเทียบใน: https://github.com/erfelipe/PDFtextExtractionฉันหวังว่าจะช่วยคุณ

Tika-Python เป็น Python ที่เชื่อมโยงกับบริการ Apache Tika ™ REST ซึ่งอนุญาตให้ Tika ถูกเรียกใช้ในชุมชน Python

from tika import parser

raw = parser.from_file("///Users/Documents/Textos/Texto1.pdf")
raw = str(raw)

safe_text = raw.encode('utf-8', errors='ignore')

safe_text = str(safe_text).replace("\n", "").replace("\\", "")
print('--- safe text ---' )
print( safe_text )

3
ขอขอบคุณเป็นพิเศษสำหรับ.encode('utf-8', errors='ignore')
Evgeny

AttributeError: โมดูล 'os' ไม่มีแอตทริบิวต์ 'setsid'
keramat

7

ด้านล่างนี้เป็นวิธีการแก้รหัสคำถามในส่วนงูหลาม 3 ก่อนเรียกใช้รหัสตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งPyPDF2ไลบรารีในสภาพแวดล้อมของคุณแล้ว หากไม่ได้ติดตั้งให้เปิดพรอมต์คำสั่งและเรียกใช้คำสั่งต่อไปนี้:

pip3 install PyPDF2

รหัสโซลูชั่น:

import PyPDF2
pdfFileObject = open('sample.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObject)
count = pdfReader.numPages
for i in range(count):
    page = pdfReader.getPage(i)
    print(page.extractText())

2
คุณจะบันทึกเนื้อหาทั้งหมดในไฟล์ข้อความเดียวและใช้เพื่อการวิเคราะห์ต่อไปอย่างไร
Rahul Agarwal

7
นี่ไม่ได้แก้ปัญหาที่กล่าวถึงในคำถามจริง
Soumik Rakshit

6

PyPDF2 ในบางกรณีจะไม่สนใจช่องว่างสีขาวและทำให้ข้อความผลลัพธ์ยุ่ง แต่ฉันใช้ PyMuPDF และฉันก็พอใจจริงๆที่คุณสามารถใช้ลิงค์นี้เพื่อรับข้อมูลเพิ่มเติม


pymupdf เป็นทางออกที่ดีที่สุดที่ฉันสังเกตเห็นไม่จำเป็นต้องใช้ไลบรารี C ++ เพิ่มเติมเช่น pdftotext หรือ java เช่น tika
Kay

pymypdf เป็นทางออกที่ดีที่สุดไม่มีเซิร์ฟเวอร์หรือไลบรารีเพิ่มเติมและทำงานกับไฟล์ที่ PyPDF2 PypDF3 PyPDF4 ดึงสตริงข้อความว่างเปล่า ขอบคุณมาก!
Andrea Bisello

ในการติดตั้ง pymupdf pip install pymupdf==1.16.16เรียกใช้ ใช้รุ่นที่เฉพาะเจาะจงเพราะวันนี้รุ่นใหม่ล่าสุด (17) ไม่ทำงาน ฉันเลือกใช้สำหรับ pymupdf \nเพราะสารสกัดจากเขตการตัดข้อความในถ่านบรรทัดใหม่ ดังนั้นฉันจึงแยกข้อความจาก pdf เป็นสตริงด้วย pymupdf จากนั้นฉันก็ใช้my_extracted_text.splitlines()เพื่อแยกข้อความเป็นบรรทัดในรายการ
erickfis

PyMuPDF น่าประหลาดใจจริงๆ ขอบคุณ
erfelipe

6

pdftotextนั้นดีที่สุดและง่ายที่สุด! pdftotext ยังสงวนโครงสร้างเช่นกัน

ฉันลอง PyPDF2, PDFMiner และอีกสองสามอย่าง แต่ก็ไม่ได้ผลที่น่าพอใจ


ข้อความดังต่อไปนี้เมื่อทำการติดตั้ง pdf2 ข้อความCollecting PDFMiner (from pdf2text)ดังนั้นฉันไม่เข้าใจคำตอบนี้เลย
zhy

pdf2text และ pdftotext นั้นแตกต่างกัน คุณสามารถใช้ลิงก์จากคำตอบ
Dharam

ตกลง. มันค่อนข้างสับสนนิดหน่อย
zhy


5

ไฟล์ PDF แบบหลายหน้าสามารถดึงออกมาเป็นข้อความเพียงเส้นเดียวแทนที่จะให้หมายเลขหน้าเป็นอาร์กิวเมนต์โดยใช้รหัสด้านล่าง

import PyPDF2
import collections
pdf_file = open('samples.pdf', 'rb')
read_pdf = PyPDF2.PdfFileReader(pdf_file)
number_of_pages = read_pdf.getNumPages()
c = collections.Counter(range(number_of_pages))
for i in c:
   page = read_pdf.getPage(i)
   page_content = page.extractText()
   print page_content.encode('utf-8')

ปัญหาเฉพาะที่นี่เนื้อหาของหน้าใหม่เขียนทับหน้าสุดท้าย
Rahul Agarwal

3

นี่คือรหัสที่ง่ายที่สุดสำหรับการแยกข้อความ

รหัส:

# importing required modules
import PyPDF2

# creating a pdf file object
pdfFileObj = open('filename.pdf', 'rb')

# creating a pdf reader object
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

# printing number of pages in pdf file
print(pdfReader.numPages)

# creating a page object
pageObj = pdfReader.getPage(5)

# extracting text from page
print(pageObj.extractText())

# closing the pdf file object
pdfFileObj.close()

แนะนำให้ใช้ 'tika'
Vineesh TP

2

ฉันพบวิธีแก้ปัญหาที่นี่PDFLayoutTextStripper

มันดีเพราะมันสามารถรักษาเลย์เอาต์ของ PDF ต้นฉบับได้ได้

มันเขียนใน Java แต่ฉันได้เพิ่ม Gateway เพื่อรองรับ Python

รหัสตัวอย่าง:

from py4j.java_gateway import JavaGateway

gw = JavaGateway()
result = gw.entry_point.strip('samples/bus.pdf')

# result is a dict of {
#   'success': 'true' or 'false',
#   'payload': pdf file content if 'success' is 'true'
#   'error': error message if 'success' is 'false'
# }

print result['payload']

ตัวอย่างผลลัพธ์จากPDFLayoutTextStripper : ป้อนคำอธิบายรูปภาพที่นี่

คุณสามารถดูรายละเอียดเพิ่มเติมได้ที่นี่Stripper with Python


2

ฉันทำงานได้ดีกว่า OCR และดูแลการจัดตำแหน่งหน้าเว็บในขณะที่แยกข้อความจาก PDF ควรได้รับการช่วยเหลือ:

from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from io import StringIO

def convert_pdf_to_txt(path):
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    fp = open(path, 'rb')
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    password = ""
    maxpages = 0
    caching = True
    pagenos=set()


    for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
        interpreter.process_page(page)


    text = retstr.getvalue()

    fp.close()
    device.close()
    retstr.close()
    return text

text= convert_pdf_to_txt('test.pdf')
print(text)

nb รุ่นล่าสุดไม่ใช้codecหาเรื่อง ฉันแก้ไขสิ่งนี้โดยการลบนั่นคือdevice = TextConverter(rsrcmgr, retstr, laparams=laparams)
atomh33ls

1

สำหรับการแยกข้อความจาก PDF ใช้โค้ดด้านล่าง

import PyPDF2
pdfFileObj = open('mypdf.pdf', 'rb')

pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

print(pdfReader.numPages)

pageObj = pdfReader.getPage(0)

a = pageObj.extractText()

print(a)

0

ฉันกำลังเพิ่มรหัสเพื่อบรรลุสิ่งนี้: มันใช้ได้ดีสำหรับฉัน:

# This works in python 3
# required python packages
# tabula-py==1.0.0
# PyPDF2==1.26.0
# Pillow==4.0.0
# pdfminer.six==20170720

import os
import shutil
import warnings
from io import StringIO

import requests
import tabula
from PIL import Image
from PyPDF2 import PdfFileWriter, PdfFileReader
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage

warnings.filterwarnings("ignore")


def download_file(url):
    local_filename = url.split('/')[-1]
    local_filename = local_filename.replace("%20", "_")
    r = requests.get(url, stream=True)
    print(r)
    with open(local_filename, 'wb') as f:
        shutil.copyfileobj(r.raw, f)

    return local_filename


class PDFExtractor():
    def __init__(self, url):
        self.url = url

    # Downloading File in local
    def break_pdf(self, filename, start_page=-1, end_page=-1):
        pdf_reader = PdfFileReader(open(filename, "rb"))
        # Reading each pdf one by one
        total_pages = pdf_reader.numPages
        if start_page == -1:
            start_page = 0
        elif start_page < 1 or start_page > total_pages:
            return "Start Page Selection Is Wrong"
        else:
            start_page = start_page - 1

        if end_page == -1:
            end_page = total_pages
        elif end_page < 1 or end_page > total_pages - 1:
            return "End Page Selection Is Wrong"
        else:
            end_page = end_page

        for i in range(start_page, end_page):
            output = PdfFileWriter()
            output.addPage(pdf_reader.getPage(i))
            with open(str(i + 1) + "_" + filename, "wb") as outputStream:
                output.write(outputStream)

    def extract_text_algo_1(self, file):
        pdf_reader = PdfFileReader(open(file, 'rb'))
        # creating a page object
        pageObj = pdf_reader.getPage(0)

        # extracting extract_text from page
        text = pageObj.extractText()
        text = text.replace("\n", "").replace("\t", "")
        return text

    def extract_text_algo_2(self, file):
        pdfResourceManager = PDFResourceManager()
        retstr = StringIO()
        la_params = LAParams()
        device = TextConverter(pdfResourceManager, retstr, codec='utf-8', laparams=la_params)
        fp = open(file, 'rb')
        interpreter = PDFPageInterpreter(pdfResourceManager, device)
        password = ""
        max_pages = 0
        caching = True
        page_num = set()

        for page in PDFPage.get_pages(fp, page_num, maxpages=max_pages, password=password, caching=caching,
                                      check_extractable=True):
            interpreter.process_page(page)

        text = retstr.getvalue()
        text = text.replace("\t", "").replace("\n", "")

        fp.close()
        device.close()
        retstr.close()
        return text

    def extract_text(self, file):
        text1 = self.extract_text_algo_1(file)
        text2 = self.extract_text_algo_2(file)

        if len(text2) > len(str(text1)):
            return text2
        else:
            return text1

    def extarct_table(self, file):

        # Read pdf into DataFrame
        try:
            df = tabula.read_pdf(file, output_format="csv")
        except:
            print("Error Reading Table")
            return

        print("\nPrinting Table Content: \n", df)
        print("\nDone Printing Table Content\n")

    def tiff_header_for_CCITT(self, width, height, img_size, CCITT_group=4):
        tiff_header_struct = '<' + '2s' + 'h' + 'l' + 'h' + 'hhll' * 8 + 'h'
        return struct.pack(tiff_header_struct,
                           b'II',  # Byte order indication: Little indian
                           42,  # Version number (always 42)
                           8,  # Offset to first IFD
                           8,  # Number of tags in IFD
                           256, 4, 1, width,  # ImageWidth, LONG, 1, width
                           257, 4, 1, height,  # ImageLength, LONG, 1, lenght
                           258, 3, 1, 1,  # BitsPerSample, SHORT, 1, 1
                           259, 3, 1, CCITT_group,  # Compression, SHORT, 1, 4 = CCITT Group 4 fax encoding
                           262, 3, 1, 0,  # Threshholding, SHORT, 1, 0 = WhiteIsZero
                           273, 4, 1, struct.calcsize(tiff_header_struct),  # StripOffsets, LONG, 1, len of header
                           278, 4, 1, height,  # RowsPerStrip, LONG, 1, lenght
                           279, 4, 1, img_size,  # StripByteCounts, LONG, 1, size of extract_image
                           0  # last IFD
                           )

    def extract_image(self, filename):
        number = 1
        pdf_reader = PdfFileReader(open(filename, 'rb'))

        for i in range(0, pdf_reader.numPages):

            page = pdf_reader.getPage(i)

            try:
                xObject = page['/Resources']['/XObject'].getObject()
            except:
                print("No XObject Found")
                return

            for obj in xObject:

                try:

                    if xObject[obj]['/Subtype'] == '/Image':
                        size = (xObject[obj]['/Width'], xObject[obj]['/Height'])
                        data = xObject[obj]._data
                        if xObject[obj]['/ColorSpace'] == '/DeviceRGB':
                            mode = "RGB"
                        else:
                            mode = "P"

                        image_name = filename.split(".")[0] + str(number)

                        print(xObject[obj]['/Filter'])

                        if xObject[obj]['/Filter'] == '/FlateDecode':
                            data = xObject[obj].getData()
                            img = Image.frombytes(mode, size, data)
                            img.save(image_name + "_Flate.png")
                            # save_to_s3(imagename + "_Flate.png")
                            print("Image_Saved")

                            number += 1
                        elif xObject[obj]['/Filter'] == '/DCTDecode':
                            img = open(image_name + "_DCT.jpg", "wb")
                            img.write(data)
                            # save_to_s3(imagename + "_DCT.jpg")
                            img.close()
                            number += 1
                        elif xObject[obj]['/Filter'] == '/JPXDecode':
                            img = open(image_name + "_JPX.jp2", "wb")
                            img.write(data)
                            # save_to_s3(imagename + "_JPX.jp2")
                            img.close()
                            number += 1
                        elif xObject[obj]['/Filter'] == '/CCITTFaxDecode':
                            if xObject[obj]['/DecodeParms']['/K'] == -1:
                                CCITT_group = 4
                            else:
                                CCITT_group = 3
                            width = xObject[obj]['/Width']
                            height = xObject[obj]['/Height']
                            data = xObject[obj]._data  # sorry, getData() does not work for CCITTFaxDecode
                            img_size = len(data)
                            tiff_header = self.tiff_header_for_CCITT(width, height, img_size, CCITT_group)
                            img_name = image_name + '_CCITT.tiff'
                            with open(img_name, 'wb') as img_file:
                                img_file.write(tiff_header + data)

                            # save_to_s3(img_name)
                            number += 1
                except:
                    continue

        return number

    def read_pages(self, start_page=-1, end_page=-1):

        # Downloading file locally
        downloaded_file = download_file(self.url)
        print(downloaded_file)

        # breaking PDF into number of pages in diff pdf files
        self.break_pdf(downloaded_file, start_page, end_page)

        # creating a pdf reader object
        pdf_reader = PdfFileReader(open(downloaded_file, 'rb'))

        # Reading each pdf one by one
        total_pages = pdf_reader.numPages

        if start_page == -1:
            start_page = 0
        elif start_page < 1 or start_page > total_pages:
            return "Start Page Selection Is Wrong"
        else:
            start_page = start_page - 1

        if end_page == -1:
            end_page = total_pages
        elif end_page < 1 or end_page > total_pages - 1:
            return "End Page Selection Is Wrong"
        else:
            end_page = end_page

        for i in range(start_page, end_page):
            # creating a page based filename
            file = str(i + 1) + "_" + downloaded_file

            print("\nStarting to Read Page: ", i + 1, "\n -----------===-------------")

            file_text = self.extract_text(file)
            print(file_text)
            self.extract_image(file)

            self.extarct_table(file)
            os.remove(file)
            print("Stopped Reading Page: ", i + 1, "\n -----------===-------------")

        os.remove(downloaded_file)


# I have tested on these 3 pdf files
# url = "http://s3.amazonaws.com/NLP_Project/Original_Documents/Healthcare-January-2017.pdf"
url = "http://s3.amazonaws.com/NLP_Project/Original_Documents/Sample_Test.pdf"
# url = "http://s3.amazonaws.com/NLP_Project/Original_Documents/Sazerac_FS_2017_06_30%20Annual.pdf"
# creating the instance of class
pdf_extractor = PDFExtractor(url)

# Getting desired data out
pdf_extractor.read_pages(15, 23)

0

คุณสามารถดาวน์โหลด tika-app-xxx.jar (ล่าสุด) จากที่นี่ที่นี่

จากนั้นวางไฟล์. jar นี้ไว้ในโฟลเดอร์เดียวกันของไฟล์สคริปต์ไพ ธ อน

จากนั้นใส่รหัสต่อไปนี้ในสคริปต์:

import os
import os.path

tika_dir=os.path.join(os.path.dirname(__file__),'<tika-app-xxx>.jar')

def extract_pdf(source_pdf:str,target_txt:str):
    os.system('java -jar '+tika_dir+' -t {} > {}'.format(source_pdf,target_txt))

ข้อดีของวิธีนี้:

การพึ่งพาน้อยลง ไฟล์. jar เดียวนั้นง่ายต่อการจัดการว่าเป็นแพคเกจหลาม

การสนับสนุนหลายรูปแบบ ตำแหน่งsource_pdfสามารถเป็นไดเรกทอรีของเอกสารประเภทใดก็ได้ (.doc, .html, .odt ฯลฯ )

ปัจจุบัน. tika-app.jar ปล่อยรุ่นก่อนหน้าของแพ็คเกจ tika python ที่เกี่ยวข้องเสมอ

มีเสถียรภาพ มีความเสถียรและบำรุงรักษาอย่างดี (Powered by Apache) มากกว่า PyPDF

ข้อเสีย:

jre-headless เป็นสิ่งที่จำเป็น


วิธีการแก้ปัญหา pythonic ทั้งหมด หากคุณแนะนำสิ่งนี้คุณควรสร้างแพคเกจหลามและให้ผู้คนนำเข้าสิ่งนั้น ไม่แนะนำให้ใช้การประมวลผลบรรทัดคำสั่งของรหัส java ในหลาม
Michael Tamillow

@MichaelTamillow ถ้าเขียนโค้ดที่กำลังจะถูกอัพโหลดเป็น pypi ฉันยอมรับว่ามันไม่ใช่ความคิดที่ดี อย่างไรก็ตามหากเป็นเพียงสคริปต์ไพ ธ อนที่มี shebang สำหรับการใช้งานชั่วคราวจะไม่เลวใช่ไหม
pah8J

คำถามไม่มีชื่อเรื่องด้วย "python" ดังนั้นฉันคิดว่าการระบุ "นี่เป็นวิธีการทำใน Java" เป็นที่ยอมรับมากกว่านี้ ในทางเทคนิคคุณสามารถทำอะไรก็ได้ที่คุณต้องการใน Python นั่นเป็นสาเหตุว่าทำไมมันทั้งน่ากลัวและแย่ การใช้งานชั่วคราวเป็นนิสัยที่ไม่ดี
Michael Tamillow

0

หากคุณลองใช้งานใน Anaconda บน Windows PyPDF2 อาจไม่สามารถจัดการไฟล์ PDF บางส่วนที่มีโครงสร้างที่ไม่ได้มาตรฐานหรืออักขระ Unicode ผมขอแนะนำให้ใช้รหัสต่อไปนี้ถ้าคุณจำเป็นต้องเปิดและอ่านมากของไฟล์แบบ PDF - ข้อความของไฟล์ PDF ทั้งหมดในโฟลเดอร์ที่มีเส้นทางญาติจะถูกเก็บไว้ในรายการ.//pdfs//pdf_text_list

from tika import parser
import glob

def read_pdf(filename):
    text = parser.from_file(filename)
    return(text)


all_files = glob.glob(".\\pdfs\\*.pdf")
pdf_text_list=[]
for i,file in enumerate(all_files):
    text=read_pdf(file)
    pdf_text_list.append(text['content'])

print(pdf_text_list)

-1

PyPDF2 ทำงานได้ แต่ผลลัพธ์อาจแตกต่างกันไป ฉันเห็นการค้นพบที่ไม่สอดคล้องกันค่อนข้างมากจากการดึงผลลัพธ์

reader=PyPDF2.pdf.PdfFileReader(self._path)
eachPageText=[]
for i in range(0,reader.getNumPages()):
    pageText=reader.getPage(i).extractText()
    print(pageText)
    eachPageText.append(pageText)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.