1. Introducción
En este codelab, aprenderás a usar el analizador de formularios de Document AI para analizar un formulario escrito a mano con Python.
Usaremos un formulario de admisión médica simple como ejemplo, pero este procedimiento funcionará con cualquier formulario generalizado compatible con DocAI.
Requisitos previos
Este codelab se basa en contenido presentado en otros codelabs de Document AI.
Recomendamos que completes los siguientes codelabs antes de continuar.
Qué aprenderás
- Cómo analizar y extraer datos de un formulario escaneado con el analizador de formularios de Document AI
Requisitos
Encuesta
¿Cómo usarás este instructivo?
¿Cómo calificarías tu experiencia en Python?
¿Cómo calificarías tu experiencia en el uso de los servicios de Google Cloud?
2. Configuración y requisitos
En este codelab, se supone que ya completaste los pasos de configuración de Document AI que se indican en el codelab de OCR de Document AI.
Completa estos pasos antes de continuar:
También deberás instalar Pandas, una biblioteca de análisis de datos de código abierto para Python.
pip3 install --upgrade pandas
3. Crea un procesador de analizador de formularios
Primero debes crear una instancia de procesador del analizador de formularios para usarla en la plataforma de Document AI para este instructivo.
- En Console, navega a Descripción general de la plataforma de Document AI
- Haz clic en Crear procesador y selecciona Analizador de formularios.

- Especifica el nombre del procesador y selecciona tu región en la lista.
- Haz clic en Crear para crear tu procesador.
- Copia el ID del procesador. Debes usarlo en el código más adelante.
Prueba el procesador en la consola de Cloud
Para probar tu procesador en la consola, puedes subir un documento. Haz clic en Subir documento y selecciona un formulario para analizar. Puedes descargar y usar este formulario de muestra si no tienes uno disponible para usar.

Tu resultado debería tener la siguiente apariencia: 
4. Descarga el formulario de muestra
Tenemos un documento de muestra que contiene un formulario simple de admisión médica.
Puedes descargar el PDF mediante el siguiente vínculo. Luego, súbelo a la instancia de Cloud Shell.
Como alternativa, puedes descargarlo de nuestro bucket público de Google Cloud Storage con gsutil.
gsutil cp gs://cloud-samples-data/documentai/codelabs/form-parser/intake-form.pdf .
Confirma que el archivo se haya descargado a Cloud Shell con el siguiente comando:
ls -ltr intake-form.pdf
5. Extrae los pares clave-valor del formulario
En este paso, usarás la API de procesamiento en línea para llamar al procesador de Form Parser que creaste anteriormente. Luego, extraerás los pares clave-valor que se encuentran en el documento.
El procesamiento en línea se usa para enviar un solo documento y esperar la respuesta. También puedes usar el procesamiento por lotes si deseas enviar varios archivos o si el tamaño del archivo supera el límite de páginas del procesamiento en línea. Puedes revisar cómo hacerlo en el Codelab de OCR.
El código para realizar una solicitud de procesamiento es idéntico para todos los tipos de procesadores, con la excepción del ID del procesador.
El objeto de respuesta Document contiene una lista de páginas del documento de entrada.
Cada objeto page contiene una lista de campos de formulario y sus ubicaciones en el texto.
El siguiente código itera en cada página y extrae cada clave, valor y puntuación de confianza. Estos son datos estructurados que se pueden almacenar más fácilmente en bases de datos o en otras aplicaciones.
Crea un archivo llamado form_parser.py y usa el código que se proporciona a continuación.
form_parser.py
import pandas as pd
from google.cloud import documentai_v1 as documentai
def online_process(
project_id: str,
location: str,
processor_id: str,
file_path: str,
mime_type: str,
) -> documentai.Document:
"""
Processes a document using the Document AI Online Processing API.
"""
opts = {"api_endpoint": f"{location}-documentai.googleapis.com"}
# Instantiates a client
documentai_client = documentai.DocumentProcessorServiceClient(client_options=opts)
# The full resource name of the processor, e.g.:
# projects/project-id/locations/location/processor/processor-id
# You must create new processors in the Cloud Console first
resource_name = documentai_client.processor_path(project_id, location, processor_id)
# Read the file into memory
with open(file_path, "rb") as image:
image_content = image.read()
# Load Binary Data into Document AI RawDocument Object
raw_document = documentai.RawDocument(
content=image_content, mime_type=mime_type
)
# Configure the process request
request = documentai.ProcessRequest(
name=resource_name, raw_document=raw_document
)
# Use the Document AI client to process the sample form
result = documentai_client.process_document(request=request)
return result.document
def trim_text(text: str):
"""
Remove extra space characters from text (blank, newline, tab, etc.)
"""
return text.strip().replace("\n", " ")
PROJECT_ID = "YOUR_PROJECT_ID"
LOCATION = "YOUR_PROJECT_LOCATION" # Format is 'us' or 'eu'
PROCESSOR_ID = "FORM_PARSER_ID" # Create processor in Cloud Console
# The local file in your current working directory
FILE_PATH = "intake-form.pdf"
# Refer to https://cloud.google.com/document-ai/docs/processors-list
# for supported file types
MIME_TYPE = "application/pdf"
document = online_process(
project_id=PROJECT_ID,
location=LOCATION,
processor_id=PROCESSOR_ID,
file_path=FILE_PATH,
mime_type=MIME_TYPE,
)
names = []
name_confidence = []
values = []
value_confidence = []
for page in document.pages:
for field in page.form_fields:
# Get the extracted field names
names.append(trim_text(field.field_name.text_anchor.content))
# Confidence - How "sure" the Model is that the text is correct
name_confidence.append(field.field_name.confidence)
values.append(trim_text(field.field_value.text_anchor.content))
value_confidence.append(field.field_value.confidence)
# Create a Pandas Dataframe to print the values in tabular format.
df = pd.DataFrame(
{
"Field Name": names,
"Field Name Confidence": name_confidence,
"Field Value": values,
"Field Value Confidence": value_confidence,
}
)
print(df)
Ejecuta el código ahora y deberías ver el texto extraído e impreso en tu consola.
Deberías ver el siguiente resultado si usas nuestro documento de muestra:
$ python3 form_parser.py
Field Name Field Name Confidence Field Value Field Value Confidence
0 Phone #: 0.999982 (906) 917-3486 0.999982
1 Emergency Contact: 0.999972 Eva Walker 0.999972
2 Marital Status: 0.999951 Single 0.999951
3 Gender: 0.999933 F 0.999933
4 Occupation: 0.999914 Software Engineer 0.999914
5 Referred By: 0.999862 None 0.999862
6 Date: 0.999858 9/14/19 0.999858
7 DOB: 0.999716 09/04/1986 0.999716
8 Address: 0.999147 24 Barney Lane 0.999147
9 City: 0.997718 Towaco 0.997718
10 Name: 0.997345 Sally Walker 0.997345
11 State: 0.996944 NJ 0.996944
...
6. Analiza tablas
El analizador de formularios también puede extraer datos de tablas dentro de documentos. En este paso, descargaremos un nuevo documento de muestra y extraeremos datos de la tabla. Dado que cargaremos los datos en Pandas, se pueden guardar en un archivo CSV y en muchos otros formatos con una sola llamada de método.
Descarga el formulario de muestra con tablas
Tenemos un documento de muestra que contiene un formulario y una tabla de muestra.
Puedes descargar el PDF mediante el siguiente vínculo. Luego, súbelo a la instancia de Cloud Shell.
Como alternativa, puedes descargarlo de nuestro bucket público de Google Cloud Storage con gsutil.
gsutil cp gs://cloud-samples-data/documentai/codelabs/form-parser/form_with_tables.pdf .
Confirma que el archivo se haya descargado a Cloud Shell con el siguiente comando:
ls -ltr form_with_tables.pdf
Extrae datos de tablas
La solicitud de procesamiento de datos de tablas es exactamente la misma que la de extracción de pares clave-valor. La diferencia radica en los campos de los que extraemos los datos en la respuesta. Los datos de la tabla se almacenan en el campo pages[].tables[].
En este ejemplo, se extrae información de las filas de encabezado y de cuerpo de cada tabla y página, luego se imprime la tabla y se guarda como un archivo CSV.
Crea un archivo llamado table_parsing.py y usa el código que se proporciona a continuación.
table_parsing.py
# type: ignore[1]
"""
Uses Document AI online processing to call a form parser processor
Extracts the tables and data in the document.
"""
from os.path import splitext
from typing import List, Sequence
import pandas as pd
from google.cloud import documentai
def online_process(
project_id: str,
location: str,
processor_id: str,
file_path: str,
mime_type: str,
) -> documentai.Document:
"""
Processes a document using the Document AI Online Processing API.
"""
opts = {"api_endpoint": f"{location}-documentai.googleapis.com"}
# Instantiates a client
documentai_client = documentai.DocumentProcessorServiceClient(client_options=opts)
# The full resource name of the processor, e.g.:
# projects/project-id/locations/location/processor/processor-id
# You must create new processors in the Cloud Console first
resource_name = documentai_client.processor_path(project_id, location, processor_id)
# Read the file into memory
with open(file_path, "rb") as image:
image_content = image.read()
# Load Binary Data into Document AI RawDocument Object
raw_document = documentai.RawDocument(
content=image_content, mime_type=mime_type
)
# Configure the process request
request = documentai.ProcessRequest(
name=resource_name, raw_document=raw_document
)
# Use the Document AI client to process the sample form
result = documentai_client.process_document(request=request)
return result.document
def get_table_data(
rows: Sequence[documentai.Document.Page.Table.TableRow], text: str
) -> List[List[str]]:
"""
Get Text data from table rows
"""
all_values: List[List[str]] = []
for row in rows:
current_row_values: List[str] = []
for cell in row.cells:
current_row_values.append(
text_anchor_to_text(cell.layout.text_anchor, text)
)
all_values.append(current_row_values)
return all_values
def text_anchor_to_text(text_anchor: documentai.Document.TextAnchor, text: str) -> str:
"""
Document AI identifies table data by their offsets in the entirety of the
document's text. This function converts offsets to a string.
"""
response = ""
# If a text segment spans several lines, it will
# be stored in different text segments.
for segment in text_anchor.text_segments:
start_index = int(segment.start_index)
end_index = int(segment.end_index)
response += text[start_index:end_index]
return response.strip().replace("\n", " ")
PROJECT_ID = "YOUR_PROJECT_ID"
LOCATION = "YOUR_PROJECT_LOCATION" # Format is 'us' or 'eu'
PROCESSOR_ID = "FORM_PARSER_ID" # Create processor before running sample
# The local file in your current working directory
FILE_PATH = "form_with_tables.pdf"
# Refer to https://cloud.google.com/document-ai/docs/file-types
# for supported file types
MIME_TYPE = "application/pdf"
document = online_process(
project_id=PROJECT_ID,
location=LOCATION,
processor_id=PROCESSOR_ID,
file_path=FILE_PATH,
mime_type=MIME_TYPE,
)
header_row_values: List[List[str]] = []
body_row_values: List[List[str]] = []
# Input Filename without extension
output_file_prefix = splitext(FILE_PATH)[0]
for page in document.pages:
for index, table in enumerate(page.tables):
header_row_values = get_table_data(table.header_rows, document.text)
body_row_values = get_table_data(table.body_rows, document.text)
# Create a Pandas Dataframe to print the values in tabular format.
df = pd.DataFrame(
data=body_row_values,
columns=pd.MultiIndex.from_arrays(header_row_values),
)
print(f"Page {page.page_number} - Table {index}")
print(df)
# Save each table as a CSV file
output_filename = f"{output_file_prefix}_pg{page.page_number}_tb{index}.csv"
df.to_csv(output_filename, index=False)
Ejecuta el código ahora y deberías ver el texto extraído e impreso en tu consola.
Deberías ver el siguiente resultado si usas nuestro documento de muestra:
$ python3 table_parsing.py
Page 1 - Table 0
Item Description
0 Item 1 Description 1
1 Item 2 Description 2
2 Item 3 Description 3
Page 1 - Table 1
Form Number: 12345678
0 Form Date: 2020/10/01
1 Name: First Last
2 Address: 123 Fake St
También deberías tener dos archivos CSV nuevos en el directorio desde el que ejecutas el código.
$ ls form_with_tables_pg1_tb0.csv form_with_tables_pg1_tb1.csv table_parsing.py
7. Felicitaciones
Felicitaciones, usaste correctamente la API de Document AI para extraer datos de un formulario escrito a mano. Te recomendamos que experimentes con otros documentos de formulario.
Realiza una limpieza
Para evitar que se generen cargos en tu cuenta de Google Cloud por los recursos que usaste en este instructivo, sigue estos pasos:
- En la consola de Cloud, ve a la página Administrar recursos.
- En la lista de proyectos, selecciona tu proyecto y haz clic en Borrar.
- En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrarlo.
Más información
Sigue aprendiendo sobre Document AI con estos codelabs de seguimiento.
- Procesadores especializados con Document AI (Python)
- Administra procesadores de Document AI con Python
- Document AI: Con interacción humana
Recursos
Licencia
Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.