View a markdown version of this page

使用 “分析贷款” 工作流程 - Amazon Textract

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 “分析贷款” 工作流程

要使用 “分析借阅” 工作流程检测多页借阅文档中的文本或分析多页借阅文档,请执行以下操作:

  1. 创建亚马逊 SNS 主题和亚马逊 SQS 队列。

  2. 为队列订阅主题。

  3. 向该主题授予向队列发送消息的权限。

  4. 开始处理文档。呼叫StartLendingAnalysis操作。

  5. 从 Amazon SQS 队列获取完成状态。示例代码跟踪Start操作返回的任务标识符 (JobId)。示例代码仅获取从完成状态中读取的匹配作业标识符的结果。如果其他应用程序使用相同的队列和主题,这一点很重要。为简单起见,示例代码会删除不匹配的作业。考虑将已删除的任务添加到 Amazon SQS 死信队列中,以便进一步调查。

    使用该 OutputConfig 功能,可以将 StartLendingAnalysis 操作结果发送到您选择的 Amazon S3 存储桶。如果您使用此功能,则可能需要对用户和服务角色进行一些其他配置。有关如何让 Amazon Textract 将加密文档发送到您的 Amazon S3 存储桶的信息,请参阅。输出配置权限

  6. 通过调用GetLendingAnalysis操作或操作来获取和显示处理结果。GetLendingAnalysisSummary

  7. 处理完文档后,请务必删除亚马逊 SNS 主题和亚马逊 SQS 队列。如果您需要处理其他文档,可以按原样保留 Amazon SNS 主题和 Amazon SQS 队列,然后将其重复用于其他文档。

执行异步贷款分析

此过程的示例代码是针对 Python 和 AWS CLI。在开始之前,请安装相应的 AWS SDK。有关更多信息,请参阅 步骤 2:设置 AWS CLI and AWS 软件开发工具包

  1. 配置用户对亚马逊 Textract 的访问权限,并配置亚马逊 Textract 对亚马逊 SNS 的访问权限。有关更多信息,请参阅为异步操作配置 Amazon Textract。要完成此过程,您需要一个 PDF 格式的多页文档文件。您可以跳过配置说明中的步骤 3 — 6,因为示例代码创建和配置 Amazon SNS 主题和 Amazon SQS 队列。如果完成 CLI 示例,则无需设置 SQS 队列。

  2. 将 PDF 或 TIFF 格式的多页文档文件上传到您的 Amazon S3 存储桶(您也可以处理 JPEG、PNG、TIFF 或 PDF 格式的单页文档)。有关说明,请参阅《亚马逊简单存储服务用户指南》中的将对象上传到 Amazon S3。

  3. 使用以下适用于 Python 的 AWS 开发工具包 (Boto3) 或 AWS CLI 代码来分析多页借阅文档中的文本。在主函数中:

    • 将的roleArn值替换为您在 Amazon Textract 访问您的亚马逊 SNS 主题中保存的 IA M 角色 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操作或操作时,请jobIdjobId返回的替换StartLendingAnalysisGetLendingAnalysisSummary将替换为您的区域名称,region-name以指定存储桶的区域。

  4. 为您选择的 SDK 或 AWS CLI 运行代码。

    此操作可能需要一段时间才能完成。完成后,将通过以下示例显示已检测或分析文本的区块列表:

    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()