EOF marker not found while use PyPDF2 merge pdf file in python

Viewed 27640

When I use the following code

from PyPDF2 import PdfFileMerger

merge = PdfFileMerger()

for newFile in nlst:
    merge.append(newFile)
merge.write("newFile.pdf")

Something happened as following:

raise utils.PdfReadError("EOF marker not found")

PyPDF2.utils.PdfReadError: EOF marker not found

Anybody could tell me what happened?

5 Answers

After encountering this problem using camelot and PyPDF2, I did some digging and have solved the problem.

The end of file marker '%%EOF' is meant to be the very last line, but some PDF files put a huge chunk of javascript after this line, and the reader cannot find the EOF.

Illustration of what the EOF plus javascript looks like if you open it:

 b'>>\r\n',
 b'startxref\r\n',
 b'275824\r\n',
 b'%%EOF\r\n',
 b'\n',
 b'\n',
 b'<script type="text/javascript">\n',
 b'\twindow.parent.focus();\n',
 b'</script><!DOCTYPE html>\n',
 b'\n',
 b'\n',
 b'\n',

So you just need to truncate the file before the javascript begins.

Solution:

def reset_eof_of_pdf_return_stream(pdf_stream_in:list):
    # find the line position of the EOF
    for i, x in enumerate(txt[::-1]):
        if b'%%EOF' in x:
            actual_line = len(pdf_stream_in)-i
            print(f'EOF found at line position {-i} = actual {actual_line}, with value {x}')
            break

    # return the list up to that point
    return pdf_stream_in[:actual_line]

# opens the file for reading
with open('data/XXX.pdf', 'rb') as p:
    txt = (p.readlines())

# get the new list terminating correctly
txtx = reset_eof_of_pdf_return_stream(txt)

# write to new pdf
with open('data/XXX_fixed.pdf', 'wb' as f:
    f.writelines(txtx)

fixed_pdf = PyPDF2.PdfFileReader('data/XXX_fixed.pdf')

One simple solution for this problem (EOF marker not found). Open your .pdf file in other application (I used Libre office draw in Ubuntu 18.04). Then export the file as .pdf. Using this exported .pdf file the problem will not persist.

I wanted to add my hacky solution to this issue.

I had the same error with python requests (application/pdf). In my case the provider (a shipping labeling service) did give a 200 and a b'string which represents the PDF, but in some random cases it missed the EOF marker.

Because it was random, I came up with the following solution:

for obj in label_objects:
    get_label = api.get_label(label_id=obj.label_id)
    while not 'EOF' in str(get_label.content):
        get_label = api.get_label(label_id=obj.label_id)

At a few tries it gives the b'string with EOF and we're good to proceed.

I've also got that problem and got a solution.

First, python reads PDF as 'rb' or 'wb' as a binary read and write format.

END OF FILE

Occurs when that there was an open parenthesis somewhere on a line, but not a matching closing parenthesis. Python reached the end of the file while looking for the closing parenthesis.

Here is the 1 solution:

  1. Close that file that you've opened earlier using this command

    newfile.close()

  2. Check whether that pdf is opened using other variable and again close it

    Same_file_with_another_variable.close()

Now open it only once and use it , you are good to go.

Related