View a markdown version of this page

使用分析貸款工作流程 - Amazon Textract

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用分析貸款工作流程

若要使用分析貸款工作流程偵測文字或分析多頁貸款文件,請執行下列動作:

  1. 建立 Amazon SNS 主題和 Amazon SQS 佇列。

  2. 訂閱 主題的佇列。

  3. 授予主題將訊息傳送至佇列的許可。

  4. 開始處理文件。呼叫StartLendingAnalysis操作。

  5. 從 Amazon SQS 佇列取得完成狀態。範例程式碼會追蹤 Start操作傳回的任務識別符 (JobId)。範例程式碼只會取得從完成狀態讀取之相符任務識別符的結果。如果其他應用程式使用相同的佇列和主題,這很重要。為了簡化,範例程式碼會刪除不相符的任務。請考慮將刪除的任務新增至 Amazon SQS 無效字母佇列,以便進一步調查。

    StartLendingAnalysis 操作的結果可以使用 OutputConfig 功能傳送到您選擇的 Amazon S3 儲存貯體。如果您使用此功能,您可能需要對使用者和服務角色執行一些額外的組態。如需如何讓 Amazon Textract 將加密文件傳送到 Amazon S3 儲存貯體的資訊,請參閱 輸出組態的許可

  6. 呼叫 GetLendingAnalysis操作或 GetLendingAnalysisSummary操作,以取得並顯示處理結果。

  7. 處理完文件後,請務必刪除 Amazon SNS 主題和 Amazon SQS 佇列。如果您需要處理其他文件,您可以將 Amazon SNS 主題和 Amazon SQS 佇列保留原樣,並重複使用於其他文件。

執行非同步貸款分析

此程序的範例程式碼適用於 Python 和 AWS CLI。開始之前,請安裝適當的 AWS SDK。如需詳細資訊,請參閱步驟 2:設定 AWS CLI 和 AWS SDKs

  1. 設定使用者存取 Amazon Textract,並設定 Amazon Textract 存取 Amazon SNS。如需詳細資訊,請參閱為非同步操作設定 Amazon Textract。若要完成此程序,您需要 PDF 格式的多頁文件檔案。您可以略過組態指示中的步驟 3 – 6,因為範例程式碼會建立和設定 Amazon SNS 主題和 Amazon SQS 佇列。如果完成 CLI 範例,您不需要設定 SQS 佇列。

  2. 將 PDF 或 TIFF 格式的多頁文件檔案上傳至 Amazon S3 儲存貯體 (您也可以處理 JPEG、PNG、TIFF 或 PDF 格式的單頁文件)。如需說明,請參閱《Amazon Simple Storage Service 使用者指南》中的將物件上傳至 Amazon S3

  3. 使用下列適用於 Python 的 AWS 開發套件 (Boto3) 或 AWS CLI 程式碼來分析多頁貸款文件中的文字。在主要函數中:

    • 將 的值取代roleArn為您在授予 Amazon Textract 存取 Amazon SNS 主題中儲存的 IAM 角色 ARN。

    • bucketdocument 的值取代為您先前在繼續步驟 2 中指定的儲存貯體和文件檔案名稱。

    • ProcessDocument函數的type輸入參數值取代為您要使用的處理類型。例如,使用 ProcessType.DETECTION 偵測文字,或使用 ProcessType.ANALYSIS 分析文字。

    • 針對 Python 範例,將 的值取代region_name為用戶端操作所在的區域。

    對於即將推出的 AWS CLI 範例程式碼,請執行下列動作:

    • 呼叫 StartLendingAnalysis 操作時,請將 的值取代bucket-name為 S3 儲存貯體的名稱,並將 取代FileName為您在步驟 2 中指定的檔案名稱。將 region-name取代為您區域的名稱,以指定儲存貯體的區域。請注意,CLI 範例不會使用 SQS。

    • 呼叫 GetLendingAnalysis 操作或 GetLendingAnalysisSummary 操作時,請將 取代jobIdStartLendingAnalysis jobId傳回的 。將 region-name取代為您區域的名稱,以指定儲存貯體的區域。

  4. 為您選擇的 SDK 或 CLI AWS 執行程式碼。

    此操作可能需要一些時間來完成。完成後,偵測或分析文字的區塊清單會以模糊範例顯示:

    AWS CLI

    若要開始貸款文件分析,請使用下列 CLI 命令。如果您想要查看分割的文件,請使用 output-config引數,否則您可以將其移除:

    aws textract start-lending-analysis \ --document-location '{"S3Object":{"Bucket":"S3Bucket","Name":"FileName"}}' \ --output-config '{"S3Bucket": "S3Bucket", "S3Prefix": "S3Prefix"}' \ --kms-key-id '1234abcd-12ab-34cd-56ef-1234567890ab' \ --region 'region-name'

    若要取得貸款文件分析的結果,請使用下列 CLI 命令。引max-results數是選用的,如果您不想限制傳回的結果數量,可以將其移除:

    aws textract get-lending-analysis \ --job-id 'jobId' \ --region 'us-west-2' \ --max-results 30

    若要擷取結果的摘要:

    aws textract get-lending-analysis-summary \ --job-id 'jobId' \ --region 'us-west-2'
    Python
    import boto3 import json import sys import time class DocumentProcessor: def __init__(self, role, bucket, document, region): self.roleArn = role self.bucket = bucket self.document = document self.region_name = region self.textract = boto3.client('textract', region_name=self.region_name) self.sqs = boto3.client('sqs') self.sns = boto3.client('sns') def ProcessDocument(self): jobFound = False response = self.textract.start_lending_analysis( DocumentLocation={'S3Object': {'Bucket': self.bucket, 'Name': self.document}}, NotificationChannel={'RoleArn': self.roleArn, 'SNSTopicArn': self.snsTopicArn}) print('Processing type: Analysis') print('Start Job Id: ' + response['JobId']) dotLine = 0 while jobFound == False: sqsResponse = self.sqs.receive_message(QueueUrl=self.sqsQueueUrl, MessageAttributeNames=['ALL'], MaxNumberOfMessages=10) if sqsResponse: if 'Messages' not in sqsResponse: if dotLine < 40: print('.', end='') dotLine = dotLine + 1 else: print() dotLine = 0 sys.stdout.flush() time.sleep(5) continue for message in sqsResponse['Messages']: notification = json.loads(message['Body']) textMessage = json.loads(notification['Message']) print(textMessage['JobId']) print(textMessage['Status']) if str(textMessage['JobId']) == response['JobId']: print('Matching Job Found:' + textMessage['JobId']) jobFound = True self.GetResults(textMessage['JobId']) self.GetSummary(textMessage['JobId']) self.sqs.delete_message(QueueUrl=self.sqsQueueUrl, ReceiptHandle=message['ReceiptHandle']) else: print("Job didn't match:" + str(textMessage['JobId']) + ' : ' + str(response['JobId'])) # Delete the unknown message. Consider sending to dead letter queue self.sqs.delete_message(QueueUrl=self.sqsQueueUrl, ReceiptHandle=message['ReceiptHandle']) print('Done!') def CreateTopicandQueue(self): millis = str(int(round(time.time() * 1000))) # Create SNS topic snsTopicName = "AmazonTextractTopic" + millis topicResponse = self.sns.create_topic(Name=snsTopicName) self.snsTopicArn = topicResponse['TopicArn'] # create SQS queue sqsQueueName = "AmazonTextractQueue" + millis self.sqs.create_queue(QueueName=sqsQueueName) self.sqsQueueUrl = self.sqs.get_queue_url(QueueName=sqsQueueName)['QueueUrl'] attribs = self.sqs.get_queue_attributes(QueueUrl=self.sqsQueueUrl, AttributeNames=['QueueArn'])['Attributes'] sqsQueueArn = attribs['QueueArn'] # Subscribe SQS queue to SNS topic self.sns.subscribe( TopicArn=self.snsTopicArn, Protocol='sqs', Endpoint=sqsQueueArn) # Authorize SNS to write SQS queue policy = """{{ "Version":"2012-10-17", "Statement":[ {{ "Sid":"MyPolicy", "Effect":"Allow", "Principal" : {{"AWS" : "*"}}, "Action":"sqs:*", "Resource": "{}", "Condition":{{ "ArnEquals":{{ "aws:SourceArn": "{}" }} }} }} ] }}""".format(sqsQueueArn, self.snsTopicArn) response = self.sqs.set_queue_attributes( QueueUrl=self.sqsQueueUrl, Attributes={ 'Policy': policy }) def DeleteTopicandQueue(self): self.sqs.delete_queue(QueueUrl=self.sqsQueueUrl) self.sns.delete_topic(TopicArn=self.snsTopicArn) # Display information about a block def DisplayExtractInfo(self, response): results = response['Results'] for page in results: print("Page Classification: {}".format(page["PageClassification"]["PageType"])) print("Page Number: {}".format(page["Page"])) for extract in page["Extractions"]: for fields, vals in extract['LendingDocument'].items(): for val in vals: print("Document Type: {}".format(val['Type'])) detections = val['ValueDetections'] for i in detections: print(i['Text']) print('Geometry') print('\tBounding Box: {}'.format(i['Geometry']['BoundingBox'])) print('\tPolygon: {}'.format(i['Geometry']['Polygon'])) def GetSummary(self, jobId): maxResults = 1000 response = self.textract.get_lending_analysis_summary(JobId=jobId, MaxResults=maxResults) doc_groups = response['DocumentGroups'] print("Summary info:") for group in doc_groups: print("Document type: " + group['Type']) split_docs = group['SplitDocuments'] for doc in split_docs: print(doc) for idx, page in doc.items(): print(str(idx) + " - " + str(page)) def GetResults(self, jobId): maxResults = 1000 paginationToken = None finished = False while finished == False: response = None if paginationToken == None: response = self.textract.get_lending_analysis(JobId=jobId, MaxResults=maxResults) else: response = self.textract.get_lending_analysis(JobId=jobId, MaxResults=maxResults, NextToken=paginationToken) print('Detected Document Text') print('Pages: {}'.format(response['DocumentMetadata']['Pages'])) self.DisplayExtractInfo(response) if 'NextToken' in response: paginationToken = response['NextToken'] else: finished = True def main(): roleArn = '' bucket = '' document = '' region_name = '' analyzer = DocumentProcessor(roleArn, bucket, document, region_name) analyzer.CreateTopicandQueue() analyzer.ProcessDocument() analyzer.DeleteTopicandQueue() if __name__ == "__main__": main()