元々は2014年からの私のHSBC銀行の分析を行いたかった。2014年は私にとって素晴らしい年あり、新しいアプリの立ち上げや、ゲームデベロップメント企業へ入社し、アパートを友達へ貸したりした年なのです。ただ、残念な事にHSBC銀行のオンラインバンキング銀行明細は残っていませんでした。数年前までしか遡れない様です。なので、2015年の明細を確認していきましょう。2015年は私にとっては結構厳しい年でした。理由は私が作ったアプリの売上が好調だったので、ゲームデベロップメント企業の仕事を辞めたのです。仕事を辞めて数週間経った頃、Google playから私のアプリが消されてしまったのです。そこから私はiPhoneのアプリ作成を開始しました。
これを作成し、 Bank Statement Converter 会社の年毎の監査の為に銀行明細のPDFから取引データを入手しようと思った。2015年までは会社は無かったので、自分の銀行明細など細かく確認した事も無かった。この投稿では私がどの様にHSBCからPDFファイルを入手し、取引データをどの様に抽出したのかを説明します。その後、興味深い取引データをカテゴリー化していきます。
HSBCからPDFの明細書をダウンロードする HSBCへログイン Internet Banking Portal バンキングへいく -> Services & Payments -> eStatement/eAdvice -> View/Manage documents. Select Month をクリックする
年と月の情報をドロップダウンボックスから選択する。2015年1月を選択します。
View Resultをクリックする。eStatements / eAdvice の選択肢が出てくると思います。
Viewボタンを押す。PDFが別のタブに出てくるはずです。
PDFの新しいタブのdownloadボタンを押す。
必要な書類が揃うまで4-7のステップを繰り返す。
この時点でだフォルダーに結構なPDFのファイルが溜まっているはずです。名前は年の次にゼロを入れた月情報を入力しました。これはPDFをアルファベット順、また日付順に並び変える事が出来るからです。これはプロゲーマーには知られた対応です。
PDFの銀行明細をエクセルへ変換する このサイトへアクセスbankstatmentconverter.com **Click here to convert a PDF!**と書いてある大きい青い文字をクリックする ダウンロードした全ての銀行明細を選択する。 ファイルがアップロードされるのを待つ。その後、下記の様な画像が出てくるはずです。 Convert all into one CSV ボタンを押す。 全ての取引詳細が確認できるページへいくはずです。ここからDownloadボタンを押してCSVを取得する事が出来ます。 分析 エクセルでCSVデータを開き、Googleシートへコピーしました。その後、各取引をカテゴリー化する為に、マニュアルでカテゴリーを追加しました。
Read more →
Grafanaを使用して色々な企業へ銀行明細変換の為のグラフやパフォーマンス指標などの作成を行っています。作成した内の一つはインターナルサーバーエラーが何回発生したかを追跡し、クライアントへ情報展開するものでした。記録をデータベースに書き込み、500以上になるとクライアントへ情報伝達をしました。この様なグラフがあると予想していなかったバグなどの対応にも便利となるのです。先週木曜日香港時間午前12:55によくJavaでは見られるサーバーからメモリ不足との警告が出始めました。
{ "message":"Java heap space", "errorType":"UNKNOWN", "cause":{ "type":"OutOfMemoryError", "detailMessage":"Java heap space", "stackTrace":[] } } 数カ月前に何度かこのエラーが発生し、この時は自分のサーバーを1 GBから4 GBへアップグレードしました。その時、私はtesseract OCR画像ベースのPDFをサーバーに取り入れていました。Tesseractは結構な量のRAMを使うので、RAM量の多いサーバーが必要だと思いました。最近tesseractをアマゾンのtextractへ変えたので、OCR画像の為のRAM追加分は不必要になりました。先週エラー表示が出た時、「サーバーが4GBなのになぜRAMが不足したのか?PDFを処理するには4GBあれば十分なはずだ」と思ったのです。ハードウェアにこれ以上の問題を与えるのではなく、コードをの効率的に利用しようと決断しました。
1. UIの問題解決 ユーザーがPDFをアップロードする際に変換ボタンを押すとUIは**/converted**のページへ飛びます。このページでUIがAPIを呼びPDF内の取引データを自動探知しようとします。もし、APIが取引データの探知に失敗っした場合、UIは**/previewPDF** ページへ飛びます。このページではユーザーが抽出箇所を選択する事ができます。ここで下記画像の様な小さなバグが見受けられます。
下4つの取引はユーザーが3秒内にAPIへの変換を4回行った事が示されています。なぜこの様な事をしたのでしょうか?これを考えるのに少し時間が掛かりましたが、やっと何が起きていたのかが分かったのです。:
1. ユーザーがPDFをアップロードする 2. ユーザーが変換ボタンを押す 3. UIが変換ページへ切り替える 4. APIにて取引の自動探知失敗のお知らせが表示される 5. UIがPDFプレビューページへ切り替える 6. ユーザーが戻るのボタンを押すと、UIは変換ページに切り替わる 7. #4に戻る 基本的にユーザーは元々のページに戻りたがるので、UIは後々PDFプレビューページへ切り替えられます。この解決法は案外簡単です。
ビフォー
if (error.errorType === 'FAILED_TO_FIND_TRANSACTIONS') { router.push('/previewPdf?uuids=' + uuid) return } アフター
if (error.errorType === 'FAILED_TO_FIND_TRANSACTIONS') { router.replace('/previewPdf?uuids=' + uuid) return } これで、最後の経歴リストPDFプレビューの最後のURLが交換されます。これはユーザーは変換ページではなく、元々のページへ飛ばされてしまうという意味を持ちます。この方がユーザーにとっても良いし、何度もAPIのサーバーへのコールが低減されるという事です。APIのコールが少ないという事はRAM使用量も低減されメモリ不足になる頻度も減少するという事になります。
2. APIファイルアップロードの効率向上 UIの問題解決後APIがコールした際のメモリ量を低減したいと考えました。まず初めに私が行った事はDEV環境へ行き、APIコールを何度もする為にUI内で何度も何度もクリックを繰り返します。その後、メモリ不足エラーを表示させる事が出来ました。このテストはDEVサーバーのRAMは1GBしか無く、PRODサーバーは4GBある為、若干不公平になっています。面白い事にファイルをアップロードする際にエラーを押す事が出来たのです。ファイルをAPIへアップロードする際は色々な事が起きているので、これが出来る事自体驚きました。ファイルのアップロード後下記が起こりました:
ファイルがきちんとPDFになっているかの検証
ファイルがテキストベースか画像ベースかきちんと分類し読み込まれているか。画像ベースの書面はOCRになっていないとダメなので、この確認を行います。
Read more →
この友好的なNABロゴはJeb Bushの 2016年 ‘Jeb!’ のロゴを連想させますね
ナショナルオーストラリア銀行 ナショナルバンクオブオーストラリアとコマーシャルバンクオブシドニーが併合し、創立したのは1982年です。
21世紀最大の銀行時価総額.
アイルランド系の子会社を持っています。 ダンスケバンク元々はナショナルアイリッシュバンクでした。
良さそうな銀行ですが、PDFも良いですかね?ローン明細を確認しながら回答しましょう。
1ページ目 最初のページのヘッダーがこちらです。そこそこな明細で、スペースも空いています。エレメントはあまり整列していませんね。例えばNABのロゴがありますが、すぐ下にテキストが掲示されています。上記画像から2つのバーコードを隠しておきました。最初のバーコードはスーパーマーケットの商品などで見かける伝統的なバーコードで、2つ目のバーコードは見た目は同じ様ですが、線の高さと厚みが異なります。
2つ目のバーコードはこの様な見た目です。インテリジェントメールバーコードただ、これはアメリカ使用でデザインされている為、あまり意味がありません。
こでが最初のページのボディーです。口座番号保持者の氏名、個人情報は隠しておきました。左側のテキストはこの書類の識別子の為、隠しておきました。取引表のヘッダーは日付、注目点、デビット、クレジット、残高 と典型的である。ヘッダーの位置合わせはデータと適合している。例えば、“日付"のバウンディングボックスの場合 、ヘッダーは"5 Jun 2021” から “19 Jul 2021"しか公差しない。
もう一度言うと、取引表には非取引データの情報も掲載されている。
日付 内容 ` `5 Jun 2021 繰り越し ` `7 Jun 2021 現在のデビットの利子は3.36%です 14 Jun 2021 2021年6月14日からのデビット利子は4.27%へなります 最後の2行は銀行口座の変更点についての説明が記されています。これらの記録は銀行口座残高には全く影響がないのです。
内容の中には、取引の利子請求に関する情報が沢山記載されています。特別な口座を使ってくれたので、利子請求を20.60引き下げた事が記載されています。2020年7月1日から2021年6月30日までの間、利子の請求額が$16,075.15である通知も入っています。この画像を詳しく見てみると画像がピクセル化されている事も分かります。これはNABがビットマップフォントを使用しているからでしょうか?
利子請求額と1,401.63の間の文字を見てください。この文字は害は無さそうですし、逆に書類を読みやすくさせているかもしれませんが、大きな混乱を引き起こします。 私のアルゴリズム. 私のアルゴリズムは文字をテキストベースにさせ文字間の距離を変えており、テキストのバウンディングボックスを使用してどのテキストのヘッダーと適合するかが決まります。こういう意味です。“利子請求額 …………………………………… 785.70” このテキストのグループは1つになり、バウンディングボックスは注目点 のコラムと繋がります。ラッキーな事にこの問題を解決する事ができたのです。
2ページ目 最終ページは担保文言の後は白紙です。この担保文言は興味深いと思いました:
後にデビットからクレジットへ変更する事もあり、その結果
私達は口座残高を適切に調整する必要があります。
以前の取引価格を調整すると言っているのでしょうか?例えば、2021年6月30日の利子額を$1401.63から$1400.00へ変更出来るという事でしょうか?銀行取引は必ず、追加のデビット、クレジット取引を行わなければいけないと思っていました。
変換結果 [結構うまく変換できます]https://bankstatementconverter.com). 本当は内容を一行にして、日付、内容、残高値を同じ行に出せれば良かったです。
Read more →
この建物内でPDFの作成が上手な方はいませんか?
お客様の銀行明細の変換のお手伝いをしている際に結構な量の明細を見てきました。ほとんどの銀行明細の構成は人間が簡単に読める様、アルゴリズムでデータが抽出しやすい様、似た様なフォーマットが使われています。標準的なフォーマットへ変換されると思われがちですが、通常銀行は他社の明細を見て、一番良さそうな明細の真似をします。銀行明細のフォーマットの品質は主観的な物であります。まずHSBC香港のクレジットカード明細のフォーマットを見てみましょう。
1ページ目 まず始めに、薄ピンクのヘッダーとフッターに目がいくと思います。カーボン紙を連想させますね。ヘッダーは2つの要素で構成されており、ロゴが左側、テキストは右側に出ています。ヘッフッターから垂直方向にみると中央に揃っていない様に見えますが、大体の見た目は良さそうです。次に書類のタイトルがあります。その次にページのカウンターがあり、これが初めての動的要素になります。左下を見ると口座名と口座住所が掲載されています。この書面から私の住所は隠しておきました。右側をみるとM01496テキストエレメントが確認できます。これは何なのかよく分かりません。‘M’は男性を意味するのか?多分違います。右側を見ていくと一つ目の表が見えます。こちらには5つの動的要素と5つのラベルが英語と中国語が表示されています。
このセクションで興味深い事は中国語テキストが選択できない事です。書面全体に中国語テキストが無かった為、画像として表示されていると思ったのですが、ありませんでした。もう少し深く掘り下げてみましょう。
まず初めに、取引表の後ろにある"プラチナム"ウォーターマークを見てみましょう。
この必要性があるか分からないが、このせいで表がやや見にくくなっている。
取引表で気になる点がここで分かりました。ぱっと見で確認すると取引リストの各取引は4つに分かれています。:
投稿日 取引日 取引内容 香港ドル金額 ただ、内容はさらに4つに分類されている様です。:
内容 場所 請求国 請求通貨 請求金額 請求通貨と請求額は香港ドルで無い場合のみ掲示されています。金額の部分で興味深い事は支払い金額CRと表示されています。という事は、クレジットカードで何か購入する場合デビットとカウントし、クレジットカードで支払いをしてもデビットとカウントされるという事です。クレジットカードの全ての請求がDBと表示される訳では無いと思いますが、明細にこれが掲載されると間際しいですし、お金を使う事に罪悪感を感じてしまいます。私の一般的な明細処理では5つの分類されている内容を解析する事ができません。 解析をカスタムで行いたい場合は喜んでお手伝いします.
フッターは標準ですが、カードを紛失した際の情報が掲載されています。後は、支払い期日などの情報です。変な事になぜか大きな空の長方形があります。これは何の為か分かりません。左下にはページの右上に掲載されいる同様の情報が掲示されています。興味深い事に右上の5つのフィールドの内4つがページ右上に掲載されている繰り返された情報でした。その情報の右側にテキストがあり、郵送での支払い方法が記載されています。その右下には感謝の言葉、またその下にはきれいなピンク色の四角があります。
2ページ目 同じピンクのヘッダー、ページ表示、口座明細詳細が表になっています。その後、大きな取引表があり、取引表内には一つの取引情報しか掲載が無く、他のデータは無意味な事が見て直ぐに分かります。次に外貨で購入した場合の手数料の情報が掲載されています。ここで書面のCRの意味の説明がありました。その後、‘ポイント還元’ 残高が表示されています。次にアップルペイに関する情報が記載されています。次に取引概要、最後に利子に関する情報が掲載されています。
3ページ目 面白い事がここで起きており、HSBCが2つの仮想定の状況が掲載されています。
$20,000のクレジットカード借り分があり、 支払い最低金額を支払った場合。このケースだと返済に26.3年掛かり、最終的にHSBC へ$70,510支払う事になる。
$20,000のクレジットカード借り分があり、$888を支払う事にした。この場合、返済に3年掛かり、最終的にHSBCへ$31,957支払う事になる。
これらの数字を確認するのは面白そうだと思いました。1番目のシナリオは確認が少し難しそうです。なぜなら最低支払い金額が分かりませんし、最低支払い金額は借り残高によって金額が変わるからです。なので、この支払いのシミュレーションをするためのコードを書きました。
1 ヵ月後の残高19637 2 ヵ月後の残高 19264 3 ヵ月後の残高 18882 ... 33 ヵ月後の残高1309 34 ヵ月後の残高 456 35 ヵ月後の残高 -419 合計支払い金額 30660.33036145866 このシミュレーションの場合、HSBCへの返済支払い合計は$30,660で35カ月で完済出来る事になります。HSBCの言っている結果とは違いますが、あちらが間違っているのか、私が間違えているのでしょうか?
変換結果 この明細をbankstatementconverter.comへ通してみると、たくさんのジャンク情報も拾ってしまいますが、結構上手くいきます。
なぜ取引表にはジャンクな物が存在しているのか? 私が思うに、昔はHSBCは担保文言を提供していなかったと思います。利益支払い表や現金還元情報などは明細に掲載されてなかったはずです。もしかしたら、ソフトを使って取引リストやPDFファイルを作成していたかもしれません。そこである日、香港政府は思いついたのです:
“人々はクレジットカードの借り金が多すぎる!それはクレジットカードを最低支払い金額支払いする恐怖を知らないからだ。法律で規定し、借り金を最低支払い金額で返済する場合どうなるかを銀行が示さなければならない様にする必要がある。”
そして、法律が通ったのですが、HSBC香港のプログラマー数名が 「ねえ、静的なテキストをPDFに追加する必要がある」と言ったのです。それからコードを作成し、追加で書面に表を作成するのは面倒だと感じ、既に存在する表の取引ライン項目として追加してしまおう、とこの方法にしたはずです。
最終意見 この明細で良い箇所もあります。ピンクエリアの読解は楽しく行う事ができました。不安定な箇所もいくつか見られました。中国語のビットマップは気に入りませんが、中国語のフォントをPDFへ取り入れる事は可能ではあると思いました。最初のページに繰り返し表示されている情報も少しばかげています。ただ、明細で一番最悪な箇所は取引表に含まれている非取引データです。これがあると、私の銀行明細変換も混乱してしまいややこしいですが、加えてこの書面を読む方にとっても面倒だと思います。
Read more →
私は香港で[Dragon King Creation Limited]と呼ばれる合同会社を持っています。(https://dragonkingcreation.com/). この会社には従業員はいません。私自身がディレクターであり、100%会社を保有しています。2015年にアンドロイドやiPhoneのアプリ販売の収益を管理する為にこの会社を立ち上げました。会社自体の収益はそんなにありませんが、正式な会社です。香港では毎年、合同会社は監査を通らなければいけません。この監査時に会計士から銀行明細、クレジットカード明細などの様々なファイルに関する質問が沢山来ます。
これが私の会計士が勤務している美しいビルです
私は銀行口座2つとクレジットカード1つ保持しています。銀行口座とクレジットカードはHSBCですが、HSBCはエクセルやCSVを作成していません。PDFの銀行明細とPDFのクレジットカード明細しかありません。なので毎年2月に、オンラインバンキング口座へいき、24の銀行明細と12のクレジットカード明細をダウンロードする必要があります。そして、それを私の会計士へメールし、私の生活を続けるのです。今年は会計士へファイルを送ったら、エクセルと全ての取引情報が送られてきました。私は彼に「どうやってPDFからエクセルへ取り込んだのか?」と聞きました。
「コピー、貼り付けでデータをエクセルへ入れた」
それを聞いた私は、彼はこの仕事を全てのクライアントに行っているのか、お客様の中には一か月取引が何千件以上あると思いますし、十個以上の口座を持っている方もいる事でしょう。会計士の友達数名に同じ事をしているのか話しをしてみました。「マニュアルでデータをエクセルへ入れている」彼らは同時にPDFからエクセルへ変換するソフトを使った事もあるが、うまくいかず、ファイル処理に数分掛かると言っていました。私は「多分他の人たちも同じ問題を抱えている事だろう。銀行明細から重要な情報だけを自動で抽出してエクセルへ変換できるものを作れないかな?」と思いました。
4つの銀行明細、クレジットカード明細を取得する事ができました:
HSBC 個人口座 HSBC クレジットカード HSBC 商用口座 Westpac 個人口座 PDFの銀行明細データは下記の様な感じです:
この様なデータへ変換したいのです
そんなに難しい事では無さそうですが、PDFの取引表の処理が難しそうです。それと、取引表の下の処理も難しそうです。加え"取引詳細"ですが、取引内容は1つなのに、コラムの行が分かれてしまっています。行を併合する場合としなくても良い場合の認識は簡単な事ではないのです。
将来的に詳細情報をおしえますが、この投稿では私がどの様にPDFの銀行明細をエクセルファイルへ変換作業を行ったのかのお話しをします。
PDFファイルからエクセルファイルへデータを移行するのはかなりややこしい事である。多くの人はマニュアルでコピーをしていると思います。この内容を自動的に変換する方法が下記になります
bankstatementconverter.comへいく Convert a PDFボタンをクリックする 変換したいPDFを選択する アップロードされるまで待つ inspect ボタンを押す アップロードしたPDFが見れるページに切り替わります
長方形をページへドラグする。下記のスクリーンショットの様なページが出るはずです。抽出したい全てのデータをドラグします。 Export Selectionsボタンをクリックします。下記のスクリーンショットの様なページが出るはずです: Download ボタンを押してください。CSVと必要としているデータのダウンロードが始まります。 以上です! 特別に必要としている物があったり、質問などありましたらお気軽に 私達へメールをください
新しいプロジェクトでプロバイダーに沢山のソーシャルメディアのサインを入れなければいけない。これを行うにはOAuthに関して学び、APIを通してFacebook、Google、Gitub、TwitterなどのOAuthプロバイダーとコミュニケーションを取る事が必要である。最初の3社は簡単に対応できるが、Twitterはそうではない。5時間かけてTwitterの書面を読み、ブログ投稿をし、ライブラリへ行き、コードを書いた。これをしてうまくいった。
ステップ1 - OAuth URLの設定とパラメーター これ使い、 KtorのOAuthパッケージ, urlProvider、consumerKey と consumerSecretを変更する必要がある。他のフィールドはそのままで良いです。
oauth("auth-oauth-twitter") { urlProvider = { "${config.appConfig.backEndBaseUrl}/auth/callback/twitter" } providerLookup = { OAuthServerSettings.OAuth1aServerSettings( name = "twitter", requestTokenUrl = "https://api.twitter.com/oauth/request_token", authorizeUrl = "https://api.twitter.com/oauth/authorize", accessTokenUrl = "https://api.twitter.com/oauth/access_token", consumerKey = "CONSUMER_KEY_FROM_TWITTER_DEV_PORTAL", consumerSecret = "CONSUMER_SECRET_FROM_TWITTER_DEV_PORTAL", ) } client = httpClient } ステップ 2 – トリガー、コールバックの最終ポイントを作成する ハンドラの設定を行い、OAuthフローのトリガーをさせる必要があり、これはKtorのパッケージで行ってくれます。もっと面白いのはコールバックURLです。TwitterコールはコールバックURLで トーケン やトーケンシークレットを使用します。APIへ依頼を出す際にはこのトーケンが必要となるのです。私の場合ユーザーのプロフィールでサインインする事が出来ますが、あなたの場合はユーザーの代わりにTweetする必要があるかもしれません。
authenticate("auth-oauth-twitter") { get("/auth/login/twitter") { // Redirects to 'authorizeUrl' automatically } get("/auth/callback/twitter") { val response = twitterTransport.getUser(principal.tokenSecret, principal.token) ?
Read more →
数週間前、オーストラリアのユーザからメールが届き、「銀行明細をアップロードしたのに、何も見れない。どうすれば変換ファイルを見る事が出来るのか?」という質問だった。Grafanaダッシュボードを確認して、ユーザーが本当にPDFベースの画像をアップロードしたか確認した所、おそらくスキャンをした明細だった。数名のユーザーから同様の質問が以前も届いていたが、スキャンされた書類はうまくいかないと伝えていた。送信フォルダーから同じ様な回答を見つけてこのユーザーへ返信をした。
彼らの言っている事は良く分るし、私のウェブサイトにはPDFの銀行明細をエクセルファイルへ変換すると記載してあり、彼女は全くその通りの事をしようとしていただけだ。もう一通メッセージを送り、なぜ出来ないかを説明した。
その後、ランニングをするために家を出た。走っている途中で大雨が降りだした為、高架下で雨宿りをした。雨が止むのを待っている間にユーザーから返事があり、スキャンした書類は出来ないという事に「とても残念に感じている」との事だった。
この時点で、ユーザーのメールの名前欄に電話番号が載っている事に気づき、「うーん。光学式文字認識のソフトウェアを使ってPDFベースの画像を読み込み、この機能のコードを作成するので数週間待ってもらえないか電話しよう」と思いつきました。なので、ユーザーへ電話を掛けました。彼女はオーストラリア、私は香港なので、電話料金もやや高めです。
「…もしもし」 彼女は怪しげに電話に出ました
「こんにちは。アンガスです。ウェブの銀行明細に関して話しをしていた者です。”
“どこから電話掛けているのですか?”
“香港です”
“ああ、そうですか”
その後、彼女の状況についてお話しをし、彼女はクライアントからの書面明細をマニュアルで確認していく必要がある為、かなりの時間を費やしているとの事でした。
「私が処理できると思います。ただ、準備が出来るまで2週間時間をください。お待ちしていただけますか?」
「はい、もちろん!」
その後、オーストラリアのコロナの状況について話しをし、電話を切ってからランニングを終えました。その後数週間、OCRソフトウェアコードで基礎的なコードを作成し、ユーザーに試してもらいました。彼女に試してみて欲しいとメールを送信した所、彼女は画像ベースの書面のアップロードに成功したのです!
電話で話しをしたのは11分位だったので、11 * $7.2 = $80の電話料金が掛かりました。それだけの価値はあったと思うので、今後ももっと多くのユーザーへ電話を掛けたいと思います。