Jak wyodrębnić tekst z pliku PDF?


190

Próbuję wyodrębnić tekst zawarty w tym pliku PDF za pomocą Python.

Korzystam z modułu PyPDF2 i mam następujący skrypt:

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

Po uruchomieniu kodu otrzymuję następujące dane wyjściowe, które różnią się od danych zawartych w dokumencie PDF:

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

Jak mogę wyodrębnić tekst z dokumentu PDF?


9
Nigdy nie używałem tego modułu, ale to robi różnicę, jeśli otworzyć plik w trybie binarnym: pdf_file = open('sample.pdf', 'rb')?
PM 2,

2
Dzięki za odpowiedź. Próbowałem tego w trybie binarnym, ale nic się nie zmieniło
Simplicity

3
Skopiuj tekst za pomocą dobrej przeglądarki PDF - kanoniczny Adobe Acrobat Reader, jeśli to możliwe. Czy otrzymujesz ten sam wynik? Różnica polega nie na tym, że tekst jest inny, ale na czcionce - kody znaków odwzorowują się na inne wartości. Nie wszystkie pliki PDF zawierają prawidłowe dane, aby je przywrócić.
usr2564301

2
Że PDF zawiera znak stół CMAP, więc ograniczenia i obejścia omówione w tym wątku to jest istotne - stackoverflow.com/questions/4203414/... .
dwarring

2
Plik PDF rzeczywiście zawiera poprawny plik CMAP, więc konwersja mapowania znaków ad hoc na zwykły tekst jest banalna. Wymaga to jednak dodatkowego przetwarzania, aby uzyskać prawidłową kolejność tekstu. Mechanizm renderowania plików PDF w systemie Mac OS X to paskudna robota! W oryginalnej kolejności renderowania otrzymuję „m T'h iuss iisn ga tosam fopllloew DalFo dnogc wumithe ntht eI tutorial” ... Dopiero po posortowaniu według współrzędnych x otrzymuję znacznie bardziej poprawny wynik: „To jest przykładowy dokument PDF I używam do śledzenia wraz z samouczkiem ".
usr2564301

Odpowiedzi:


199

Szukałem prostego rozwiązania dla Pythona 3.x i Windows. Wydaje się, że nie ma wsparcia z textract , co jest niefortunne, ale jeśli szukasz prostego rozwiązania dla systemu Windows / Python 3, sprawdź pakiet tika , naprawdę proste do czytania plików pdf.

Tika-Python jest powiązaniem Pythona z usługami REST Apache Tika ™, które umożliwiają natywne wywoływanie Tiki w społeczności Python.

from tika import parser # pip install tika

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

Zauważ, że Tika jest napisana w Javie, więc będziesz musiał zainstalować Java Runtime


17
Testowałem pypdf2, tika i próbowałem i nie udało mi się zainstalować textract i pdftotext. Pypdf2 zwrócił 99 słów, a tika zwróciła wszystkie 858 słów z mojej faktury testowej. Więc skończyłem z tika.
Stian

8
Człowieku, kocham cię. Nie wiem, dlaczego tak dobra odpowiedź jest ukryta w StackOverflow. Wszyscy wspominają, że musimy używać PyPDF2 lub pdfminer, ale śmierdzą. Jestem teraz zakochany w tika
jxpython

15
Wciąż pojawia się błąd „RuntimeError: Nie można uruchomić serwera Tika”.
Nav

3
Odpowiedź Przez całe życie szukałem, dlaczego nikt inny nie poleca Tiki? Dzięki!
Jacob-Jan Mosselman,

4
Jeśli chcesz uruchomić to na wszystkich plikach PDF w katalogu (rekurencyjnie), weź ten skrypt
Hope

58

Użyj textract.

Obsługuje wiele rodzajów plików, w tym pliki PDF

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

24
Textwrap wydaje się być przyjemnym opakowaniem, ale polega na wielu narzędziach innych niż Python, które mogą nie być łatwo dostępne w danym systemie.
David Brown

1
Działa z plikami PDF, epub itp. - przetwarza pliki PDF, których nawet PDFMiner nie działa.
Ulad Kasach

jak go używać w aws lambda, próbowałem tego, ale wystąpił błąd importu z textract
Arun Kumar

5
textractto opakowanie dla Poppler:pdftotext(między innymi).
onewhaleid

1
@ArunKumar: Aby użyć czegokolwiek w AWS Lambda, które nie jest wbudowane, musisz uwzględnić to i wszystkie dodatkowe zależności w pakiecie.
Jeff Learman

51

Spójrz na ten kod:

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')

Dane wyjściowe to:

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

Użycie tego samego kodu do odczytu pliku pdf z 201308FCR.pdf . Wyjście jest normalne.

Jego dokumentacja wyjaśnia dlaczego:

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: Dostajesz coś za page_content? Jeśli tak, to sprawdź, czy to pomaga, używając innego kodowania niż (utf-8)
Quinn

Najlepszą biblioteką, którą znalazłem do czytania pliku pdf przy użyciu Pythona, jest „tika”
Vineesh TP

201308FCR.pdf nie znaleziono.
Chaitanya Bapat

30

Po wypróbowaniu textract (który wydawał się mieć zbyt wiele zależności) i pypdf2 (który nie mógł wyodrębnić tekstu z pdfów, z którymi testowałem) i tika (który był zbyt wolny) skończyłem na użyciu pdftotextz xpdf (jak już zasugerowałem w innej odpowiedzi) i właśnie wywołałem plik binarny bezpośrednio z Pythona (może być konieczne dostosowanie ścieżki do 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')

Istnieje pdftotext, który robi to samo, ale zakłada, że ​​pdftotext znajduje się w / usr / local / bin, podczas gdy ja używam tego w AWS lambda i chciałem go użyć z bieżącego katalogu.

Btw: Aby użyć tego na lambda, musisz wprowadzić funkcję binarną i zależność do libstdc++.soswojej funkcji lambda. Osobiście potrzebowałem skompilować xpdf. Ponieważ instrukcje tego wysadziłyby tę odpowiedź, umieściłem je na moim osobistym blogu .


4
O mój boże, to działa !! Wreszcie rozwiązanie, które wyodrębnia tekst we właściwej kolejności! Chcę cię przytulić do tej odpowiedzi! (Lub jeśli nie lubisz uścisków, oto wirtualna kawa / piwo / ...)
DonQuiKong

4
cieszę się, że pomogło! Upvoting daje takie samo wrażenie jak przytulanie, więc czuję się dobrze!
hansaplast

proste ... gr8 po wyjęciu z pudełka!
shantanu pathak

10

Zamiast tego możesz użyć xPDF o sprawdzonym czasie i pochodnych narzędzi do wyodrębnienia tekstu, ponieważ pyPDF2 nadal wydaje się mieć różne problemy z wyodrębnianiem tekstu.

Długa odpowiedź brzmi: istnieje wiele odmian sposobu kodowania tekstu w pliku PDF i może wymagać dekodowania samego łańcucha PDF, następnie może być konieczne mapowanie za pomocą CMAP, a następnie może być konieczne przeanalizowanie odległości między słowami i literami itp.

Jeśli plik PDF jest uszkodzony (tzn. Wyświetla prawidłowy tekst, ale podczas kopiowania powoduje śmieci) i naprawdę musisz wyodrębnić tekst, możesz rozważyć konwersję PDF na obraz (za pomocą ImageMagik ), a następnie użyj Tesseract, aby uzyskać tekst z obrazu za pomocą OCR.


-1, ponieważ OP prosi o odczytanie plików pdf w Pythonie i chociaż istnieje opakowanie xpdf dla Pythona, jest ono źle obsługiwane.
cduguet,

9

Wypróbowałem wiele konwerterów plików PDF w Pythonie i lubię aktualizować tę recenzję. Tika jest jedną z najlepszych. Ale PyMuPDF to dobra wiadomość od użytkownika @ehsaneha.

Zrobiłem kod, aby je porównać: https://github.com/erfelipe/PDFtextExtraction Mam nadzieję, że ci pomogę.

Tika-Python jest powiązaniem Pythona z usługami REST Apache Tika ™, które umożliwiają natywne wywoływanie Tiki w społeczności 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
Specjalne podziękowania za.encode('utf-8', errors='ignore')
Evgeny

AttributeError: moduł „os” nie ma atrybutu „setsid”
keramat

7

Poniższy kod jest rozwiązaniem pytania w Pythonie 3 . Przed uruchomieniem kodu upewnij się, że masz zainstalowaną PyPDF2bibliotekę w swoim środowisku. Jeśli nie jest zainstalowany, otwórz wiersz polecenia i uruchom następujące polecenie:

pip3 install PyPDF2

Kod rozwiązania:

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
W jaki sposób zapisałeś całą zawartość w jednym pliku tekstowym i wykorzystałeś ją do dalszej analizy
Rahul Agarwal

7
To nie rozwiązuje problemu wymienionego w rzeczywistym pytaniu.
Soumik Rakshit

7

PyPDF2 w niektórych przypadkach ignoruje białe znaki i sprawia, że ​​tekst wynikowy jest bałaganem, ale używam PyMuPDF i jestem bardzo zadowolony, że możesz użyć tego linku, aby uzyskać więcej informacji


pymupdf to najlepsze rozwiązanie, jakie zaobserwowałem, nie wymaga dodatkowych bibliotek C ++, takich jak pdftotext lub java, takich jak tika
Kay

pymypdf jest naprawdę najlepszym rozwiązaniem, bez dodatkowego serwera lub bibliotek, i działa z plikiem, w którym PyPDF2 PypDF3 PyPDF4 pobiera pusty ciąg tekstu. Wielkie dzięki!
Andrea Bisello

aby zainstalować pymupdf, uruchom pip install pymupdf==1.16.16. Używanie tej konkretnej wersji, ponieważ dzisiaj najnowsza wersja (17) nie działa. Zdecydowałem się na pymupdf, ponieważ wyodrębnia pola zawijania tekstu w nowym wierszu char \n. Więc wyodrębniam tekst z pdf do ciągu za pomocą pymupdf, a następnie używam my_extracted_text.splitlines()do podzielenia tekstu na linie na listę.
erickfis

PyMuPDF był naprawdę zaskakujący. Dzięki.
erfelipe

6

pdftotext jest najlepszy i najprostszy! pdftotext również rezerwuje strukturę.

Próbowałem PyPDF2, PDFMiner i kilku innych, ale żaden z nich nie dał zadowalającego rezultatu.


Komunikat jest następujący podczas instalowania pdf2text, Collecting PDFMiner (from pdf2text)więc nie rozumiem teraz tej odpowiedzi.
zhy

pdf2text i pdftotext są różne. Możesz użyć linku z odpowiedzi.
Dharam

DOBRZE. To trochę mylące.
zhy


5

Wielostronicowy pdf można wyodrębnić jako tekst w jednym odcinku zamiast podawać indywidualny numer strony jako argument przy użyciu poniższego kodu

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')

Jedynym problemem tutaj jest to, że treść nowej strony zastępuje ostatnią
Rahul Agarwal

3

Oto najprostszy kod do wyodrębniania tekstu

kod:

# 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()

Zalecane „tika”
Vineesh TP

2

Tutaj znalazłem rozwiązanie PDFLayoutTextStripper

To dobrze, ponieważ może zachować układ oryginalnego pliku PDF .

Jest napisany w Javie, ale dodałem Gateway do obsługi Pythona.

Przykładowy kod:

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']

Przykładowe dane wyjściowe z pliku PDFLayoutTextStripper : wprowadź opis zdjęcia tutaj

Możesz zobaczyć więcej szczegółów tutaj Stripper with Python


2

Mam lepszą pracę niż OCR i utrzymanie wyrównania strony podczas wyodrębniania tekstu z pliku PDF. Powinien być pomocny:

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)

Uwaga Najnowsza wersja nie używa już codecarg . Naprawiłem to, usuwając go tj.device = TextConverter(rsrcmgr, retstr, laparams=laparams)
atomh33ls

1

Do wyodrębnienia tekstu z pliku PDF użyj poniższego kodu

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

pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

print(pdfReader.numPages)

pageObj = pdfReader.getPage(0)

a = pageObj.extractText()

print(a)

0

Dodaję kod, aby to osiągnąć: Działa dla mnie dobrze:

# 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

Można pobrać tika-app-xxx.jar (ostatni) z tutaj .

Następnie umieść ten plik .jar w tym samym folderze pliku skryptu python.

następnie wstaw następujący kod do skryptu:

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))

Zaletą tej metody:

mniejsza zależność. Pojedynczym plikiem .jar łatwiej jest zarządzać tym pakietem python.

obsługa wielu formatów. Pozycja source_pdfmoże być katalogiem dowolnego rodzaju dokumentu. (.doc, .html, .odt itp.)

aktualny. Plik tika-app.jar zawsze wypuszcza się wcześniej niż odpowiednia wersja pakietu tika python.

stabilny. Jest o wiele bardziej stabilny i dobrze utrzymany (Powered by Apache) niż PyPDF.

niekorzyść:

Niezbędny jest bezgłowy.


całkowicie nie pytonowe rozwiązanie. Jeśli to zalecasz, powinieneś zbudować pakiet python i pozwolić, aby ludzie go zaimportowali. Nie zaleca się korzystania z wykonywania kodu Java w wierszu polecenia w języku Python.
Michael Tamillow,

@MichaelTamillow, jeśli piszę kod, który ma zostać przesłany do pypi, przyznaję, że nie jest to dobry pomysł. Jeśli jednak jest to tylko skrypt Pythona z shebang do tymczasowego użytku, nie jest źle, prawda?
pah8J

Cóż, pytanie nie jest zatytułowane „python” - więc myślę, że stwierdzenie „oto jak to zrobić w Javie” jest bardziej dopuszczalne niż to. Technicznie w Pythonie możesz robić, co chcesz. Dlatego jest zarówno niesamowity, jak i okropny. Tymczasowe używanie jest złym nawykiem.
Michael Tamillow

0

Jeśli wypróbujesz to w Anaconda w systemie Windows, PyPDF2 może nie obsługiwać niektórych plików PDF ze niestandardową strukturą lub znakami Unicode. Polecam użycie następującego kodu, jeśli chcesz otworzyć i odczytać wiele plików pdf - tekst wszystkich plików pdf w folderze ze ścieżką względną .//pdfs//zostanie zapisany na liście 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 działa, ale wyniki mogą się różnić. Widzę dość niespójne ustalenia z ekstrakcji wyników.

reader=PyPDF2.pdf.PdfFileReader(self._path)
eachPageText=[]
for i in range(0,reader.getNumPages()):
    pageText=reader.getPage(i).extractText()
    print(pageText)
    eachPageText.append(pageText)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.