PowerShellでEDINETのAPIを叩く(開示情報)
株式投資や取引先管理など、開示情報が必要な時があります。 そこで電子的な方法で閲覧するためのサイトがEDINETです。
EDINETにはWebAPIがあるので、今回はこれを呼び出してデータを取得してみます。
環境
- Windows 10 Pro
- PowerShell 5.1
まずは規約から
プログラムを作る上で必ず気をつけないといけないのは禁止事項でしょうか。
第5条(禁止事項)
1.利用者は、以下に掲げる行為を行ってはならないものとします。
(1) 本機能の健全な運営を害する一切の行為
(2) 短時間における大量のアクセスその他の本機能の運用に支障を与える行為
バグとかで連続で呼び出しまくる、ような事はないように気をつけましょう。
なお、各ガイドラインやAPIの使用については「操作ガイド」ページにあります。
API
APIは2つあり、これらを関数にしてみました。
書類一覧取得 API
function Get-DocumentList { <# .SYNOPSIS EDINET API 書類一覧APIの呼び出し .DESCRIPTION 書類一覧APIを呼び出し、結果を取得する。 .EXAMPLE Get-DocumentList -Date (Get-Date) -DataType DocumentListAndMetadata #> param ( # ファイル日付 [Parameter(Mandatory, Position = 0, ValueFromPipeline)] [datetime] $Date, # 取得情報 [Parameter(Mandatory, Position = 1)] [ValidateSet('OnlyMetadata', 'DocumentListAndMetadata')] [string] $DataType ) $parameter = @{ date = Get-Date -Date $Date -Format yyyy-MM-dd type = switch ($DataType) { 'OnlyMetadata' { 1 } 'DocumentListAndMetadata' { 2 } } } return Invoke-RestMethod ` -Method Get ` -Uri https://disclosure.edinet-fsa.go.jp/api/v1/documents.json ` -Body $parameter }
書類取得 API
function Get-Document { <# .SYNOPSIS EDINET API 書類取得APIの呼び出し .DESCRIPTION 書類取得APIを呼び出し、結果を取得する。 取得が正常にできなかった場合は例外を発生させる。 .EXAMPLE Get-Document -DocumentId "S1000001" -DocumentType DocumentAndReportAndXbrlZip #> param ( # 書類ID [Parameter(Mandatory, Position = 0, ValueFromPipeline)] [string] $DocumentId, # 必要書類 [Parameter(Mandatory, Position = 1)] [ValidateSet('DocumentAndReportAndXbrlZip', 'PDF', 'AlternativeZip', 'InEnglishZip')] [string] $DocumentType ) $parameter = @{ type = switch ($DocumentType) { 'DocumentAndReportAndXbrlZip' { 1 } 'PDF' { 2 } 'AlternativeZip' { 3 } 'InEnglishZip' { 4 } } } $response = Invoke-WebRequest ` -Method Get ` -Uri https://disclosure.edinet-fsa.go.jp/api/v1/documents/$DocumentId ` -Body $parameter if ($response.Content -is [Byte[]]) { return $response.Content } else { throw $response.Content } }
サンプル
以下のような流れを想定して、上記の関数を使った処理を書いてみました。
- 書類一覧API:メタデータのみを取得する。
- メタデータの件数が以前取得した件数と異なる場合
- 書類一覧を取得する。
- 未取得の書類に対して、PDFデータを取得して保存する。
- 次の処理の間隔分待つ
- 終了条件をチェックし、終了する。
function Sample { $invalidFileNameChars = [System.IO.Path]::GetInvalidFileNameChars() $today = Get-Date $count = 0 $savedDocIDs = @() while ($true) { # メタデータのみ取得して、今回のループの書類件数を取得する。 $metadata = Get-DocumentList -Date $today -DataType OnlyMetadata $latestCount = $metadata.metadata.resultset.count # 取得した件数が以前の件数と異なっている場合は新しい書類がアップロードされている。 if ($latestCount -ne $count) { $currentDocuments = Get-DocumentList -Date $today -DataType DocumentListAndMetadata # 追加された書類を取得 $addedDocuments = $currentDocuments.results | Where-Object { $savedDocIDs -notcontains $_.docID } # 追加された書類それぞれ、PDFを取得して保存する。 $addedDocuments | ForEach-Object { $docData = Get-Document -DocumentId $_.docID -DocumentType PDF $filename = "$($_.filerName)-$($_.docDescription).pdf" $invalidFileNameChars | ForEach-Object { $filename = $filename.Replace($_, '_') } [System.IO.File]::WriteAllBytes($filename, $docData) # 取得データの間隔を設定する Start-Sleep -Seconds 10 } # 保存済の書類IDを更新 $savedDocIDs = $currentDocuments.results | Select-Object -ExpandProperty docID } # 最新の件数を反映して次のループへ。 $count = $latestCount # 10分待つ Start-Sleep -Seconds 600 # ループを出る。ここに何らかの条件(時刻や経過時間判定)を入れてループの終了を行う。 if ($true) { break } } }
APIを触ってみての感想
Invoke-WebRequestの Content の中にJSON形式の文字列でステータスコードが帰ってくるのが少し混乱しましたが、割と簡単に利用できるAPIだと思いました。
XBRLやZIPファイルの解凍まで含めると結構作り込みが必要そうですが、PDF程度なら手軽に実装できます。
試してみてはいかがでしょうか。
以上!