Microsoft Foundry上でドキュメントから情報抽出をしてみた
Microsoft Foundryには様々なサービスが用意されていて、その中には、ドキュメント内のテキストデータを抽出するサービスもある。
今回は、Microsoft Foundry上でドキュメントを読み込みテキストデータを抽出してみたので、その手順を共有する。
前提条件
下記記事の「Microsoft Foundryへのログインとプロジェクト作成」が完了していること。
情報抽出の手順
Microsoft Foundry上の情報抽出(Content Understanding – ドキュメント レイアウト アナライザー)サービスは、デプロイしなくても画面から実行できる。また、APIキーを指定してAPIで呼び出すことができる。その手順は、以下の通り。
1) Microsoft Foundryにログインし、「ビルド」メニューを押下する。

2)「サービス」メニューを押下後、「Content Understanding – ドキュメント レイアウト アナライザー」メニューを押下する。

4) 請求書PDFファイルを取り込むため、「ファイルの参照」リンクを押下する。

ちなみに、上記PDFファイルは、下記サイトのテンプレートファイル(請求書シート)をPDF出力したものである。
https://www.robotpayment.co.jp/service/mikata/template/invoice/01.html
5) 読み込むPDFファイルを選択し「開く」ボタンを押下する。

6) 以下のように、PDFファイルの内容が読み取られたことが確認できる。

7) 読み込んだPDFファイルの内容を分析するため、「分析の実行」ボタンを押下する。

8) 以下のように、PDFファイルの請求書が読み取られたことが確認できる。

また、「テーブル」タブの内容は以下の通りで、表データの各値が読み込まれているのが確認できる。


さらに、「結果」タブの抜粋は以下の通りで、読み取った請求書がJSON形式で出力されるのが確認できる。


また、「結果」タブの「テーブル1(請求金額(税込))」の部分を抜粋した内容は、以下の通り。
tables: [
{
"rowCount": 1,
"columnCount": 2,
"cells": [
{
"kind": "content",
"rowIndex": 0,
"columnIndex": 0,
"rowSpan": 1,
"columnSpan": 1,
"content": "請求金額(税込)",
"source": "D(1,0.9502,2.1888,2.3704,2.1887,2.3699,2.5074,0.9501,2.5076)",
"span": {
"offset": 122,
"length": 8
},
"elements": [
"/paragraphs/5"
]
},
{
"kind": "content",
"rowIndex": 0,
"columnIndex": 1,
"rowSpan": 1,
"columnSpan": 1,
"content": "¥407,957,393-",
"source": "D(1,2.3704,2.1887,4.0597,2.1891,4.0598,2.5077,2.3699,2.5074)",
"span": {
"offset": 140,
"length": 13
},
"elements": [
"/paragraphs/6"
]
}
],
"source": "D(1,0.9356,2.1031,4.0432,2.1003,4.0512,2.4981,0.9437,2.4995)",
"span": {
"offset": 105,
"length": 68
}
},
9)「コード」ボタンを押下すると、サンプルコードが表示されるため、表示されたソースコードをコピーする。

10) 9)でコピーしたソースコードのうち、上部のコメントを省略したものは、以下の通り。
import json
from urllib.parse import urlparse
from azure.ai.contentunderstanding import ContentUnderstandingClient
from azure.ai.contentunderstanding.models import AnalysisInput, AnalysisResult
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import AzureError
from azure.identity import DefaultAzureCredential
def is_absolute_url(value: str) -> bool:
parsed_url = urlparse(value)
return bool(parsed_url.scheme and parsed_url.netloc)
def main() -> None:
# Insert the following configurations.
# 1) AZURE_CONTENT_UNDERSTANDING_ENDPOINT - the endpoint to your Content Understanding resource.
endpoint = "https://stanahas-8273-resource.services.ai.azure.com/"
# 2) CONTENT_UNDERSTANDING_KEY - your Content Understanding API key (optional if using DefaultAzureCredential).
key = "{{CONTENT_UNDERSTANDING_KEY}}"
# 3) FILE_URL - you can replace this with your own URL.
file_url = "{{FILE_URL}}"
# ANALYZER_ID - the ID of the analyzer to use.
analyzer_id = "prebuilt-layout"
# API_VERSION - the API version to use.
api_version = "2026-06-01-preview"
# Validate Endpoint
if not is_absolute_url(endpoint):
print("[Error] Invalid Endpoint. Please provide a valid 'Endpoint'.")
return
# Validate File URL
if not is_absolute_url(file_url):
print("[Error] Invalid File URL. Please provide a valid URL.")
return
# Set up Content Understanding client.
hasKey = type(key) is str and bool(key.strip()) and "{{CONTENT_UNDERSTANDING_KEY}}" not in key
credential = AzureKeyCredential(key) if hasKey else DefaultAzureCredential()
client = ContentUnderstandingClient(endpoint=endpoint, credential=credential, api_version=api_version)
# [START analyze]
print(f"Analyzing with {analyzer_id} analyzer...")
print(f" File URL: {file_url}\n")
try:
poller = client.begin_analyze(
analyzer_id=analyzer_id,
inputs=[AnalysisInput(url=file_url)],
)
result: AnalysisResult = poller.result()
except AzureError as err:
print(f"[Azure Error]: {err.message}")
return
except Exception as ex:
print(f"[Unexpected Error]: {ex}")
return
# [END analyze]
# [START output_result]
print("=" * 50)
print("Analysis result:")
print("=" * 50 + "\n")
max_display_lines = 50
result_str = json.dumps(result.as_dict(), indent=2)
ret_lines = result_str.splitlines()
if len(ret_lines) > max_display_lines:
print("\n".join(ret_lines[:max_display_lines]))
print(f"\n {len(ret_lines) - max_display_lines} more lines to be displayed...\n")
else:
print(result_str)
# [END output_result]
if __name__ == "__main__":
main()11) 10)の内容を、ローカル端末上のソースコード「analyze_pdf.py」に貼り付ける。なお、読み込み用PDF「template_01.pdf」も同フォルダに配置するものとする。

12) 11)で貼り付けたソースコードを以下のように変更し、文字コードをUTF-8にした状態で貼り付ける。
import json
from urllib.parse import urlparse
from azure.ai.contentunderstanding import ContentUnderstandingClient
from azure.ai.contentunderstanding.models import AnalysisInput, AnalysisResult
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import AzureError
from azure.identity import DefaultAzureCredential
def is_absolute_url(value: str) -> bool:
parsed_url = urlparse(value)
return bool(parsed_url.scheme and parsed_url.netloc)
def main() -> None:
# Insert the following configurations.
# AZURE_CONTENT_UNDERSTANDING_ENDPOINT - the endpoint to your Content Understanding resource.
endpoint = "https://stanahas-8273-resource.services.ai.azure.com/"
# FILE_PATH、FILE_TYPE
local_file_path = "template_01.pdf"
content_type = "application/pdf" # ファイルに合わせたMIMEタイプを指定
# ANALYZER_ID - the ID of the analyzer to use.
analyzer_id = "prebuilt-layout"
# API_VERSION - the API version to use.
api_version = "2026-06-01-preview"
# Validate Endpoint
if not is_absolute_url(endpoint):
print("[Error] Invalid Endpoint. Please provide a valid 'Endpoint'.")
return
# ローカルファイルをバイナリ(bytes)として読み込み
print(f"ローカルファイル '{local_file_path}' を読み込んでいます...")
with open(local_file_path, "rb") as f:
file_bytes = f.read()
# Set up Content Understanding client.
credential = DefaultAzureCredential()
client = ContentUnderstandingClient(endpoint=endpoint, credential=credential, api_version=api_version)
# [START analyze]
print(f"Analyzing with {analyzer_id} analyzer...")
try:
poller = client.begin_analyze_binary(
analyzer_id=analyzer_id,
binary_input=file_bytes,
content_type=content_type
)
result: AnalysisResult = poller.result()
except AzureError as err:
print(f"[Azure Error]: {err.message}")
return
except Exception as ex:
print(f"[Unexpected Error]: {ex}")
return
# [END analyze]
# [START output_result]
print("=" * 50)
print("Analysis result:")
print("=" * 50 + "\n")
max_display_lines = 50
result_str = json.dumps(result.as_dict(), indent=2, ensure_ascii=False) # 日本語の文字化け防止対応にensure_ascii=Falseを追加
ret_lines = result_str.splitlines()
# 結果が長い場合は、先頭の50行のみ抽出結果を表示する
if len(ret_lines) > max_display_lines:
print("\n".join(ret_lines[:max_display_lines]))
print(f"\n {len(ret_lines) - max_display_lines} more lines to be displayed...\n")
else:
print(result_str)
# [END output_result]
if __name__ == "__main__":
main()13) 下記サイトの「Azure上でのAzure Functions動作検証」手順に従って、「az login」コマンドでログインする。
14) 12)のプログラムを実行する際、情報抽出用のライブラリが必要なので、「pip install azure.ai.contentunderstanding」コマンドを実行しインストールする。

15)「analyze_pdf.py」を実行すると、結果が、8)で「結果」タブに出力されたJSONと同形式で出力されることが確認できる。

要点まとめ
- Microsoft Foundryには様々なサービスが用意されていて、その中には、ドキュメント内のテキストデータを抽出するサービスが含まれている。







