1. מבוא
ב-Codelab הזה תלמדו איך להשתמש ב-Document AI Form Parser כדי לנתח טופס בכתב יד באמצעות Python.
נשתמש בטופס פשוט של קבלת מטופל כדוגמה, אבל התהליך הזה יעבוד עם כל טופס כללי שנתמך על ידי DocAI.
דרישות מוקדמות
ה-Codelab הזה מבוסס על תוכן שמוצג ב-Codelabs אחרים של Document AI.
מומלץ להשלים את ה-Codelabs הבאים לפני שממשיכים.
מה תלמדו
- איך מנתחים ומחלצים נתונים מטופס סרוק באמצעות הכלי Document AI Form Parser.
מה תצטרכו
סקר
איך תשתמשו במדריך הזה?
איך היית מדרג את חוויית השימוש שלך ב-Python?
איזה דירוג מתאים לדעתך לחוויית השימוש שלך בשירותי Google Cloud?
2. הגדרה ודרישות
ב-codelab הזה מניחים שהשלמתם את שלבי ההגדרה של Document AI שמפורטים ב-Document AI OCR Codelab.
לפני שממשיכים, צריך לבצע את הפעולות הבאות:
תצטרכו גם להתקין את Pandas, ספרייה בקוד פתוח לניתוח נתונים ב-Python.
pip3 install --upgrade pandas
3. יצירת מעבד לניתוח טפסים
כדי להשתמש ב-Document AI Platform במדריך הזה, צריך קודם ליצור מופע של מעבד Form Parser.
- במסוף, עוברים אל Document AI Platform Overview.
- לוחצים על יצירת מעבד ובוחרים באפשרות ניתוח טופס
. - מציינים את שם המעבד ובוחרים את האזור מהרשימה.
- לוחצים על יצירה כדי ליצור את המעבד.
- מעתיקים את מזהה המעבד. תצטרכו להשתמש בערך הזה בקוד בהמשך.
בדיקת המעבד ב-Cloud Console
כדי לבדוק את המעבד במסוף, אפשר להעלות מסמך. לוחצים על העלאת מסמך ובוחרים טופס לניתוח. אם אין לכם טופס זמין, אתם יכולים להוריד את הטופס לדוגמה הזה ולהשתמש בו.

הפלט שלכם אמור להיראות כך: 
4. הורדת טופס לדוגמה
יש לנו מסמך לדוגמה שמכיל טופס פשוט לקבלת מידע רפואי.
אפשר להוריד את קובץ ה-PDF באמצעות הקישור הבא. לאחר מכן מעלים אותו למופע Cloud Shell.
לחלופין, ניתן להוריד אותו מקטגוריה ציבורית של Cloud Storage באמצעות gsutil.
gsutil cp gs://cloud-samples-data/documentai/codelabs/form-parser/intake-form.pdf .
כדי לוודא שהקובץ הורד ל-Cloud Shell, מריצים את הפקודה הבאה:
ls -ltr intake-form.pdf
5. חילוץ צמדי מפתח/ערך מטופס
בשלב הזה תשתמשו ב-API לעיבוד אונליין כדי להפעיל את מעבד ניתוח הטפסים שיצרתם קודם. לאחר מכן, תחלצו את צמדי המפתח/ערך שנמצאים במסמך.
עיבוד אונליין מיועד לשליחת מסמך יחיד ולהמתנה לתגובה. אפשר גם להשתמש בעיבוד באצווה אם רוצים לשלוח כמה קבצים או אם גודל הקובץ חורג מהמספר המקסימלי של הדפים בעיבוד אונליין. ב-OCR Codelab מוסבר איך עושים את זה.
הקוד ליצירת בקשת עיבוד זהה לכל סוגי המעבדים, מלבד מזהה המעבד.
אובייקט התגובה Document מכיל רשימה של דפים ממסמך הקלט.
כל אובייקט page מכיל רשימה של שדות בטופס והמיקומים שלהם בטקסט.
הקוד הבא מבצע איטרציה בכל דף ומחלץ כל מפתח, ערך וציון מהימנות. אלה נתונים מובנים שאפשר לאחסן בקלות רבה יותר במסדי נתונים או להשתמש בהם באפליקציות אחרות.
יוצרים קובץ בשם form_parser.py ומשתמשים בקוד שבהמשך.
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)
מריצים את הקוד ועכשיו אמור להופיע הטקסט שחולץ והודפס במסוף.
אם משתמשים במסמך לדוגמה שלנו, הפלט אמור להיראות כך:
$ 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. ניתוח טבלאות
כלי הניתוח של טפסים יכול גם לחלץ נתונים מטבלאות במסמכים. בשלב הזה נוריד מסמך לדוגמה חדש ונחלץ נתונים מהטבלה. מכיוון שאנחנו טוענים את הנתונים ל-Pandas, אפשר להוציא את הנתונים האלה לקובץ CSV ולפורמטים רבים אחרים באמצעות הפעלת method יחידה.
הורדת טופס לדוגמה עם טבלאות
יש לנו מסמך לדוגמה שמכיל טופס לדוגמה וטבלה.
אפשר להוריד את קובץ ה-PDF באמצעות הקישור הבא. לאחר מכן מעלים אותו למופע Cloud Shell.
לחלופין, ניתן להוריד אותו מקטגוריה ציבורית של Cloud Storage באמצעות gsutil.
gsutil cp gs://cloud-samples-data/documentai/codelabs/form-parser/form_with_tables.pdf .
כדי לוודא שהקובץ הורד ל-Cloud Shell, מריצים את הפקודה הבאה:
ls -ltr form_with_tables.pdf
חילוץ נתונים מטבלה
בקשת העיבוד של נתוני הטבלה זהה לבקשת העיבוד של חילוץ זוגות של מפתח וערך. ההבדל הוא השדות שמהם אנחנו מחלצים את הנתונים בתשובה. נתוני הטבלה מאוחסנים בשדה pages[].tables[].
בדוגמה הזו, המידע מחולץ משורות הכותרת ומשורות הגוף של כל טבלה ודף, ואז הטבלה מודפסת ונשמרת כקובץ CSV.
יוצרים קובץ בשם table_parsing.py ומשתמשים בקוד שבהמשך.
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)
מריצים את הקוד ועכשיו אמור להופיע הטקסט שחולץ והודפס במסוף.
אם משתמשים במסמך לדוגמה שלנו, הפלט אמור להיראות כך:
$ 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
בנוסף, אמורים להיות שני קובצי CSV חדשים בספרייה שממנה מריצים את הקוד.
$ ls form_with_tables_pg1_tb0.csv form_with_tables_pg1_tb1.csv table_parsing.py
7. מזל טוב
הצלחתם להשתמש ב-Document AI API כדי לחלץ נתונים מטופס בכתב יד. מומלץ להתנסות במסמכי טופס אחרים.
ניקוי
כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה:
- במסוף Cloud, נכנסים לדף Manage resources.
- ברשימת הפרויקטים, בוחרים את הפרויקט ולוחצים על Delete (מחיקה).
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
מידע נוסף
כדי להמשיך ללמוד על Document AI, אפשר לעבור לשיעורי ה-Codelab הבאים.
- מעבדים ייעודיים עם Document AI (Python)
- ניהול מעבדים של Document AI באמצעות Python
- Document AI: האדם שבתהליך
מקורות מידע
רישיון
עבודה זו מורשית תחת רישיון Creative Commons שמותנה בייחוס 2.0 כללי.