<jupyter_start><jupyter_text>Interact with PDF FilesPDF files have become a sort of necessary evil these days. Despite their frequent use,PDFs are some of the most difficult files to work with in terms of making modifications,combining files, and especially for extracting text information.We are going to install a library called PyPDF2. On a linux machine we will do:$	pip	install	PyPDF2On a Windows machine using AnacondaStart - > anaconda3 -> anaconda prompt![](img/anaconda_prompt.png)And then in the command prompt, type:> conda install -c conda-forge pypdf2![](img/anaconda_prompt2.png)  Interactuar con archivos PDFLos archivos PDF se han convertido en una especie de mal necesario en estos días. A pesar de su uso frecuente,Los archivos PDF son algunos de los archivos más difíciles de trabajar en términos de modificaciones,combinando archivos, y especialmente para extraer información de texto.Vamos a instalar una biblioteca llamada PyPDF2. En una máquina Linux, haremos:$ pip install PyPDF2En una máquina con Windows que usa AnacondaInicio -> anaconda3 -> anaconda prompt![](img/anaconda_prompt.png)Y luego en el símbolo del sistema, escriba:> conda install -c conda-forge pypdf2![](img/anaconda_prompt2.png) The	PyPDF2	package	includes	a	PdfFileReader	and	a	PdfFileWriter;	just	like	whenperforming	other	types	of	file	input/output,	reading	and	writing	are	two	entirely	separateprocesses. El paquete PyPDF2 incluye un PdfFileReader y un PdfFileWriter; justo como cuandorealizar otros tipos de entrada / salida de archivo, leer y escribir son dos cosas completamente separadasprocesos.<jupyter_code>import os
from PyPDF2 import PdfFileReader

print('We have now imported modules')<jupyter_output><empty_output><jupyter_text>First,	let's	get	started	by	reading	in	some	basic	information	from	a	sample	PDF	file,	thefirst	couple	chapters	of	Jane	Austen's	Pride	and	Prejudice	via	Project	Gutenberg: Primero, empecemos leyendo información básica de un archivo PDF de muestra, los primeros dos capítulos de Orgullo y prejuicio de Jane Austen a través del Proyecto Gutenberg:<jupyter_code>input_file_name =  os.path.abspath("./pdf/Pride_and_Prejudice.pdf")
input_file = PdfFileReader(open(input_file_name,"rb"))

print("Number of pages:",input_file.getNumPages())
print("Title:",input_file.getDocumentInfo().title)<jupyter_output><empty_output><jupyter_text>We created a PdfFileReader object named   input_file   by passing a   file()   objectwith   rb   (read binary) mode and giving the full path of the file. The additional "binary"part is necessary for reading PDF files because we aren't just reading basic text data.PDFs include much more complicated information, and saying "rb" here instead of just"r" tells Python that we might encounter characters that can't be represented as standardreadable text.We also have access to certain attributes through the getDocumentInfo() method; in fact, if we displaythe result of simply calling this method, we will see a dictionary with all of the availabledocument info: Creamos un objeto PdfFileReader llamado input_file pasando un objeto file () con el modo rb (read binary) y dando la ruta completa del archivo. La parte "binaria" adicional es necesaria para leer archivos PDF porque no solo estamos leyendo datos de texto básicos. Los PDF incluyen información mucho más complicada, y decir "rb" aquí en lugar de simplemente "r" le dice a Python que podríamos encontrar caracteres que no se pueden representar como texto legible estándar.También tenemos acceso a ciertos atributos a través del método getDocumentInfo (); de hecho, si mostramos el resultado de simplemente llamar a este método, veremos un diccionario con toda la información del documento disponible:<jupyter_code>print(input_file.getDocumentInfo())<jupyter_output><empty_output><jupyter_text>Formatting standards in PDFs are inconsistent at best, and it's usually necessary to takea look at the PDF files you want to use on a case-by-case basis. In this instance, noticehow we don't actually see newline characters in the output; instead, it appears that newlines are being represented as multiple spaces in the text extracted by PyPDF2. We canuse this knowledge to write out a roughly formatted version of the book to a plain text file(for instance, if we only had the PDF available and wanted to make it readable on anuntalented (err dumb) mobile device): Los estándares de formato en archivos PDF son inconsistentes en el mejor de los casos, y generalmente es necesario analizar los archivos PDF que desea usar caso por caso. En este caso, observe cómo realmente no vemos caracteres de nueva línea en el resultado; en cambio, parece que las nuevas líneas se representan como espacios múltiples en el texto extraído por PyPDF2. Podemos usar este conocimiento para escribir una versión aproximadamente formateada del libro en un archivo de texto sin formato (por ejemplo, si solo teníamos el PDF disponible y queríamos que fuera legible en un dispositivo móvil sin talento (err tonto)):<jupyter_code>output_file_name = os.path.abspath("./temp/Pride_and_Prejudice.txt")
output_file = open(output_file_name, "w")
title = input_file.getDocumentInfo().title # get the file title
total_pages = input_file.getNumPages() # get the total page count
output_file.write(title + "\n")
output_file.write("Number of pages: {}\n\n".format(total_pages))
for page_num in range(0, total_pages):
    text = input_file.getPage(page_num).extractText()
    text = text.replace("  ", "\n")
    output_file.write(text)
output_file.close()
print("We have now printed out all the text to file")<jupyter_output><empty_output><jupyter_text>Since we're writing out basic text, we chose the plain   w   mode and created a filebook.txt in the "Output" folder. Meanwhile, we still use   rb   mode to read data from thePDF file since, before we can extract the plain text from each page, we are in factreading much more complicated data. We loop over every page number in the PDF file,extracting the text from that page. Since we know that new lines will show up asadditional spaces, we can approximate better formatting by replacing every instance ofdouble spaces (  " "  ) with a newline character. Instead of extracting text, we might want to modify the PDF file itself, saving out a newversion of the PDF. We'll see more examples of why and how this might occur in thenext section, but for now create the simplest "modified" file by saving out only a section of the original file. Here we copy over the first three pages of the PDF (not including thecover page) into a new PDF file: Como estamos escribiendo texto básico, elegimos el modo plain w y creamos un archivo book.txt en la carpeta "Salida". Mientras tanto, todavía usamos el modo rb para leer los datos del archivo PDF ya que, antes de que podamos extraer el texto sin formato de cada página, de hecho estamos leyendo datos mucho más complicados. Recorrimos cada número de página en el archivo PDF, extrayendo el texto de esa página. Como sabemos que las nuevas líneas se mostrarán como espacios adicionales, podemos aproximarnos al mejor formato reemplazando cada instancia de espacios dobles ("") con un carácter de nueva línea.En lugar de extraer texto, es posible que deseemos modificar el archivo PDF en sí, guardando una nueva versión del PDF. Veremos más ejemplos de por qué y cómo podría ocurrir esto en la próxima sección, pero por ahora cree el archivo "modificado" más simple guardando solo una sección del archivo original. Aquí copiamos las primeras tres páginas del PDF (sin incluir la página de portada) en un nuevo archivo PDF:<jupyter_code>import os
from PyPDF2 import PdfFileReader, PdfFileWriter

input_file_name = os.path.abspath("./pdf/Pride_and_Prejudice.pdf")
input_file = PdfFileReader(open(input_file_name, "rb"))
output_PDF = PdfFileWriter()
for page_num in range(1, 4):
    output_PDF.addPage(input_file.getPage(page_num))
output_file_name = os.path.abspath("./temp/portion.pdf")
output_file = open(output_file_name, "wb")
output_PDF.write(output_file)
output_file.close()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.053074353581590995, 'fraction_numerical': 0.00235061239638748, 'mean_word_length': 5.4260731319554845, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '622149', 'license': 'Apache-2.0', 'n_tokens_mistral': 2399, 'n_tokens_neox': 2363, 'n_words': 1085, 'path': '1_Interact_with_pdfs.ipynb', 'repo_name': 'pgryko/intro_to_python_col', 'size': '8083'}