Combinar PDFs y extraer un intervalo de páginas con pypdf
Combina varios PDFs en un solo archivo, extrae un intervalo inclusivo de páginas en un segundo archivo y verifica el número y el orden de las páginas resultantes. Un conjunto sintético de páginas en blanco con dimensiones deliberadamente diferentes permite comprobar el resultado manualmente.
Contenido revisado 2026.09.20Incluye archivos de ejemplo
Ver el índice
La traducción se ha realizado con IA. Comprueba el código, las unidades y los valores junto con el original. La revisión por hablantes nativos de cada idioma aún no se ha completado. English
Para quién esEsta guía está dirigida a personas que necesitan combinar PDFs o extraer páginas seleccionadas sin modificar los documentos originales.
Preparación
Python 3.12 y un comando de terminal que inicie esa versión.
pypdf instalado con python -m pip install pypdf.
Una carpeta de trabajo donde los scripts puedan crear carpetas dentro de outputs.
Espacio suficiente en disco para los source PDFs, merged PDF y extracted PDF.
01Definir las reglas de combinación y extracción
El workflow utiliza tres source PDFs en un orden explícito: alpha.pdf, beta.pdf y después gamma.pdf. Sus pages se añaden a un único merged PDF. Un segundo output extrae después las pages 2 through 5 del merged PDF utilizando la numeración humana habitual, donde la primera página es page 1.
Las sequences de Python utilizan zero-based indexes, pero este script acepta START_PAGE y END_PAGE como one-based inclusive page numbers. Por tanto, pages 2 through 5 corresponden a las Python slice positions 1 through 4, implementadas como merged_reader.pages[START_PAGE - 1:END_PAGE].
02Crear tres PDFs sintéticos
Los PDFs siguientes son sintéticos y fueron creados específicamente para este artículo. Cada page está en blanco, pero todas tienen width y height diferentes. Esto permite comprobar el page order de forma independiente sin necesitar otro PDF-generation package.
python
from pathlib import Path
from pypdf import PdfWriter
SOURCE_DIR = Path("outputs") / "pdf_merge_split_demo"
PDFS = {
"alpha.pdf": [(100, 200), (110, 210)],
"beta.pdf": [(120, 220)],
"gamma.pdf": [(130, 230), (140, 240), (150, 250)],
}
SOURCE_DIR.parent.mkdir(parents=True, exist_ok=True)
SOURCE_DIR.mkdir() # Stop if the synthetic source already exists.
for filename, page_sizes in PDFS.items():
writer = PdfWriter()
for width, height in page_sizes:
writer.add_blank_page(width=width, height=height)
target = SOURCE_DIR / filename
with target.open("xb") as stream:
writer.write(stream)
text
python create_pdf_demo.py
Source PDF
Pages
Dimensiones de página en orden
alpha.pdf
2
100×200, 110×210
beta.pdf
1
120×220
gamma.pdf
3
130×230, 140×240, 150×250
Los tres source files contienen 6 pages en total: 2 + 1 + 3. Las dimensions se expresan en PDF user-space units. Su finalidad aquí es únicamente dar a cada synthetic page una signature reconocible.
03Determinar el orden esperado de las páginas
Como los inputs se enumeran explícitamente, el merged PDF debería contener primero las dos pages de alpha, después la page de beta y, por último, las tres pages de gamma. Por tanto, el merged result debería contener 6 pages.
Merged page
Source
Dimensiones esperadas
1
alpha.pdf page 1
100×200
2
alpha.pdf page 2
110×210
3
beta.pdf page 1
120×220
4
gamma.pdf page 1
130×230
5
gamma.pdf page 2
140×240
6
gamma.pdf page 3
150×250
Por tanto, extraer las merged pages 2 through 5 debería producir exactamente 4 pages con dimensions 110×210, 120×220, 130×230 y 140×240 en ese orden.
04Combinar los archivos y extraer las pages 2 through 5
Guarda el script siguiente como pdf_merge_split.py. Valida cada input file, rechaza encrypted PDFs en este ejemplo sencillo, combina todas las pages, vuelve a abrir el merged output para verificarlo y después crea el page-range file solicitado.
python
from pathlib import Path
from pypdf import PdfReader, PdfWriter
SOURCE_DIR = Path("outputs") / "pdf_merge_split_demo"
INPUTS = ("alpha.pdf", "beta.pdf", "gamma.pdf")
OUTPUT_DIR = Path("outputs") / "pdf_merge_split_result"
MERGED = OUTPUT_DIR / "merged.pdf"
EXTRACTED = OUTPUT_DIR / "pages_2_to_5.pdf"
START_PAGE = 2
END_PAGE = 5
def page_size(page) -> tuple[int, int]:
width = int(float(page.mediabox.width))
height = int(float(page.mediabox.height))
return width, height
def main() -> None:
source_root = SOURCE_DIR.resolve(strict=True)
if not source_root.is_dir():
raise ValueError("SOURCE_DIR must be a directory.")
if START_PAGE < 1 or END_PAGE < START_PAGE:
raise ValueError("Invalid page range.")
input_paths = [source_root / name for name in INPUTS]
for path in input_paths:
if not path.is_file():
raise FileNotFoundError(f"Missing input PDF: {path}")
OUTPUT_DIR.parent.mkdir(parents=True, exist_ok=True)
OUTPUT_DIR.mkdir() # Refuse to reuse an existing result folder.
expected_sizes = []
writer = PdfWriter()
for path in input_paths:
reader = PdfReader(path)
if reader.is_encrypted:
raise ValueError(f"Encrypted PDF is not supported here: {path.name}")
for page in reader.pages:
expected_sizes.append(page_size(page))
writer.add_page(page)
with MERGED.open("xb") as stream:
writer.write(stream)
merged_reader = PdfReader(MERGED)
if merged_reader.is_encrypted:
raise RuntimeError("Unexpected encrypted merged PDF.")
merged_sizes = [page_size(page) for page in merged_reader.pages]
if merged_sizes != expected_sizes:
raise RuntimeError("Merged page count or order does not match the inputs.")
if END_PAGE > len(merged_reader.pages):
raise ValueError(
f"Requested page {END_PAGE}, but merged PDF has only "
f"{len(merged_reader.pages)} pages."
)
selected_pages = merged_reader.pages[START_PAGE - 1:END_PAGE]
extracted_writer = PdfWriter()
expected_extract_sizes = []
for page in selected_pages:
expected_extract_sizes.append(page_size(page))
extracted_writer.add_page(page)
with EXTRACTED.open("xb") as stream:
extracted_writer.write(stream)
extracted_reader = PdfReader(EXTRACTED)
extracted_sizes = [page_size(page) for page in extracted_reader.pages]
if extracted_sizes != expected_extract_sizes:
raise RuntimeError("Extracted PDF does not match the selected pages.")
print(f"Merged {len(INPUTS)} PDFs into {len(merged_reader.pages)} pages.")
print(
f"Extracted pages {START_PAGE}-{END_PAGE}: "
f"{len(extracted_reader.pages)} pages."
)
print(f"Merged output: {MERGED.as_posix()}")
print(f"Extracted output: {EXTRACTED.as_posix()}")
if __name__ == "__main__":
main()
text
python pdf_merge_split.py
05Comparar los outputs esperados
El primer output, merged.pdf, debería contener 6 pages. El segundo output, pages_2_to_5.pdf, debería contener 4 pages. La extracción incluye ambos extremos porque el script convierte los human page numbers en el Python slice correspondiente.
06Comprobar el resultado antes de utilizar PDFs reales
Abre merged.pdf y confirma que tenga 6 pages.
Abre pages_2_to_5.pdf y confirma que tenga exactamente 4 pages.
Inspecciona page dimensions u otra visible page feature para confirmar que el orden en el archivo extraído sea 110×210, 120×220, 130×230, 140×240.
Confirma que alpha.pdf, beta.pdf y gamma.pdf sigan existiendo sin cambios en la source folder.
Ejecuta de nuevo el script sin cambiar OUTPUT_DIR. Debería detenerse con FileExistsError en lugar de sustituir los PDFs anteriores.
En documentos reales, inspecciona también visualmente el page content. Que los counts coincidan por sí solo no permite detectar todos los posibles problemas, como un input order inesperado o un source PDF cuyos page labels difieran de sus physical page positions.
07Reconocer errores comunes
Síntoma
Qué comprobar
ModuleNotFoundError: No module named pypdf
Instala pypdf en el mismo Python environment con python -m pip install pypdf.
FileNotFoundError
Comprueba SOURCE_DIR, INPUTS y el working directory de la terminal. Para este ejemplo, ejecuta primero el synthetic setup script.
FileExistsError
La result folder ya existe. Revisa los outputs anteriores y elige una nueva folder en lugar de sobrescribirlos.
Encrypted PDF is not supported here
Utiliza una decrypted copy permitida o añade un password-handling workflow explícito y adecuado para tus documents.
Requested page is beyond the merged PDF
Comprueba el merged page count y los valores one-based START_PAGE y END_PAGE.
Merged or extracted verification mismatch
Considera el generated file como unverified. Comprueba los inputs y utiliza una output folder nueva en la siguiente ejecución.
Si ocurre una exception después de crear OUTPUT_DIR, pueden quedar partial files. El script no los elimina automáticamente. Mantén los failed outputs separados de los verified files.
08Comprender los límites
Este workflow verifica physical page count y page dimensions, no semantic content. No compara rendered pixels, extracted text, annotations, forms, bookmarks, named destinations, attachments, signatures ni accessibility structure.
Los PDF page labels pueden diferir de las physical page positions. Un document puede mostrar roman numerals o custom labels aunque pypdf siga accediendo a sus page objects mediante zero-based sequence position. Los valores START_PAGE y END_PAGE de este tutorial se refieren a physical sequence positions, no a printed page numbers.
Algunos PDFs complejos contienen interactive forms, digital signatures, encrypted content, unusual object relationships u otras features que requieren un tratamiento más cuidadoso. Combinar un digitally signed PDF en un nuevo document no conserva el significado de la signature original como una firma sobre el nuevo file creado. Para records importantes, revisa los PDF requirements relevantes antes de considerar una merged copy equivalente al original.
Registro de ejecución y verificación
2026-09-20 · ejemplo revisado manualmente · objetivo: Python 3.12 · se requiere pypdf · sin ejecución
Se contaron manualmente los source page totals de 2, 1 y 3, para un total de 6 merged pages.
Se siguieron manualmente las merged dimensions esperadas como 100x200, 110x210, 120x220, 130x230, 140x240 y 150x250.
Se convirtió manualmente el human page range inclusivo 2-5 en las Python positions 1 through 4 y se confirmó que contiene 4 pages.
Se obtuvieron manualmente las extracted dimensions como 110x210, 120x220, 130x230 y 140x240.
Se revisó el código para confirmar que los source PDFs se abren para lectura, los outputs se escriben en una carpeta separada y una output folder existente hace que la ejecución se detenga.
Se revisó la lógica de comparación de page-count y page-dimension y se obtuvo manualmente la salida de consola esperada.
Límites de la verificación
El código no fue ejecutado por el autor de esta respuesta; aquí no se crearon, combinaron, extrajeron ni abrieron PDF files.
No se probaron encrypted PDFs, forms, annotations, bookmarks, digital signatures, attachments, page labels ni malformed PDFs.
Las page-dimension checks verifican el orden en el ejemplo sintético, pero no demuestran semantic equivalence para PDFs reales arbitrarios.
Las URL de la documentación oficial se proporcionaron a partir de ubicaciones de documentación conocidas, pero no se comprobaron en línea.
Las explicaciones y los ejemplos son de elaboración propia. Puedes consultar los comportamientos y conceptos relacionados en las siguientes fuentes oficiales.
Encuentra filas con coincidencia exacta en las cuatro columnas y recopílalas en un nuevo archivo de Excel junto con sus números de fila originales. Revisa cada grupo de duplicados, incluida su primera aparición.
Valida las fechas y las horas de trabajo de un CSV y después guarda los recuentos mensuales de registros y las horas totales como un CSV y un gráfico de barras.
Antes de convertir una tabla en texto, alinea el objeto, el periodo, el denominador y la unidad. Usa una tabla sintética de resultados mensuales para comprobar un valor que cambió de 80 % a 82 % y una conversión de unidades, y después crea una lista de comprobación reutilizable.
Combina hojas de cálculo que utilizan las mismas columnas en una única tabla de Excel, registrando de qué hoja procede cada fila. Un pequeño libro sintético permite verificar manualmente el orden de las filas, los recuentos y los totales.