【#08】プログラム完全初心者がPythonを触ってみた(試行錯誤の末ようやく最初の段階が終わる)

 前の記事はこちら。
midoliko-tsuki.hatenablog.com

  1. 結果フォルダを作成。フォルダ名は「ocr_作業した日時(yymmddhhmmss)」
  2. PDFフォルダのファイル名リストを取得
  3. ファイル名リストからPDFを選び出して変換対象リストを作る
  4. 変換対象リストから変換対象ファイルを選択する
  5. 変換対象ファイルの最後3文字をtxtに置換した文字列を作る
  6. 結果フォルダ内にテキストファイルを新規作成する。ファイル名は前項で作った、変換対象ファイルの最後3文字をtxtに置換した文字列
  7. 変換対象ファイルを画像に変換
  8. OCR
  9. テキストデータに変換する
  10. テキストファイルに保存して閉じる

 前回の記事で、ようやく1が終わりました。

 次はPDFフォルダのファイル名リストを取得する部分です。
 調べてみたらosとかpathlibとかいろいろあって混乱したのですが、読んでてなんとか理解できたこちらの記事を参考に、globモジュールを使ってみました。
weblabo.oscasierra.net

 で、この後どうしたらいいのか分からなくて夫に助けを求めてしまいました。

# ファイル数分だけ繰り返す
for oneFullPath in strFiles:

    # ファイルの場合
    if os.path.isfile(oneFullPath):
     
        # フルパスからファイル名を抽出
        strFileName = os.path.basename(oneFullPath)

 とりあえずこれだけ書いてもらった。

 後から理解したんですが、私はfor文がよく分かっていなかったのでした。「for 変数 in オブジェクト」の最初の変数で「知らない人出てきた! 誰!?!?」となってつまづいていたようです。どういう人なのかのキャラづけは後から自分でやるんですね。知らんわ! 自己紹介なしで飛び込んでくる知らない人こわい! ちゃんと名乗って!!

 あと、出てくる文字列が変数なのか関数なのか分かってない(なんのためにVSCodeを使っているのか)、変数に何が入っているのか分かっていないのでどうしていいのか分からなくなる、というのがあり、これについては変数の名前を工夫しなさいと言われました。格好悪くてもいいので、自分で見て、これがなんなのか、何に使うのか分かる名前をつけた方がいい、と。夫は「このへんは賛否両論あるとこだけど」とつけ加えていましたが、少なくともいまの私はそういう名前のつけ方をしたほうがいいなと思いました。

 で、続いては、抽出したファイル名から後ろ3文字を削る工程です。
 こちらの記事を参考にしました。
pg-chain.com

 えっ[ ]だけで文字が削れるの!? 簡単やん!? と感動したのですが、自分でやってみたら「pdf」だけが大量に切り取られて絶望しました。結局ここも夫に書いてもらいました。いまブログを書くために見返していてようやく理解しました。ブログ役に立ってるう(前向き)。

        #末尾が.pdfであれば
        if strFileName[-4:] == ".pdf":

            # ファイル名から後ろ3文字を削る
            strTxtName = strFileName[:-3]

            #ファイル名
            strTxtName = strTxtName + "txt"

「txt」を足してファイル名にするところだけようやく自分で書けました。

 ファイル名ができたところで、テキストファイルを作成します。
office54.net
 参考にしたのはこちら。


 さてこのあとは前にもやった工程です。PDFを画像に変換して、画像をOCRして、テキストデータに変換する。そのあと、テキストデータをテキストファイルに書き込んで、ファイルを閉じる。

# ファイルを作成
            f = open(strTxtName, 'w')
        
            # 画像オブジェクトからテキストに
            # テキストファイルに書き込む
            for image in images:
                txt = tool.image_to_string(
                    image,
                    lang=lang,
                    builder=pyocr.builders.TextBuilder()
                )
                f.write(txt)

            # ファイルを閉じる
            f.close()

 も、もしかして完成してしまったのでは〜!? と動かしてみたら、動きました。
 動いたのですが、できあがったテキストファイルが、苦心惨憺して作った現在時刻を名前にしたフォルダではなく、なぜか実行ファイルのあるフォルダに保存されていく! なんでや!
 ……見返してみて気づいたのですが、テキストファイルを新規作成するときに、保存先のパスを指定していませんでした。そりゃこうなりますね……。

 別にこのままでも構わないといえば構わないのですが(手動で移動させれば済む話)、まあまあ頑張って作ったフォルダなので使われてほしい。というわけで、今度はパスを指定しないといけません。

 なので今度は、テキストファイル保存先のパスを指定しないといけません。

 参考にしたのはこちら。
python.keicode.com

 フォルダ名はdir_name、ファイル名がstrTxtNameだからこれを足せばいけるのでは?

  
            # 結果ファイルのパスを指定
          resultPath=os.path.join(dir_name,strTxtName)

            # ファイルを作成
            f = open(resultPath, 'w')

 どや! とやってみたらエラーが出ました。なんでや! エラーメッセージを頑張って読んでみたら、そんなフォルダはないよって言ってるみたいでした。よくよく見返してみたら、dir_nameに入ってるのはフォルダの名前だけでパスではありませんでした。どうもすみません。


 これでどうだ!!!

            # 結果ファイルのパスを指定
            resultPath=os.path.join(path,dir_name,strTxtName)

            # ファイルを作成
            f = open(resultPath, 'w')

 で、できた〜!!!!!!!!!

 これでようやく、やりたいことの第一段階が終わりました。長かった……。

【#07】プログラム完全初心者がPythonを触ってみた(現在時刻を名前に入れたフォルダを作る)

 前の記事はこちら。
midoliko-tsuki.hatenablog.com


 ブログを書きながら調べ物しながらプログラムを書くのは分かりやすくていいのですが、ノートパソコンの狭い画面ではだんだんしんどくなってきました。広いモニタがほしい。

 それはさておき、実際にコードを書いてみようの巻です。

  1. 結果フォルダを作成。フォルダ名は「ocr_作業した日時(yymmddhhmmss)」
  2. PDFフォルダのファイル名リストを取得
  3. ファイル名リストからPDFを選び出して変換対象リストを作る
  4. 変換対象リストから変換対象ファイルを選択する
  5. 変換対象ファイルの最後3文字をtxtに置換した文字列を作る
  6. 結果フォルダ内にテキストファイルを新規作成する。ファイル名は前項で作った、変換対象ファイルの最後3文字をtxtに置換した文字列
  7. 変換対象ファイルを画像に変換
  8. OCR
  9. テキストデータに変換する
  10. テキストファイルに保存して閉じる

 importは最初にまとめて書いといたらいいよ、と言われたのでまとめて書くことにしました。なんでだろう、その都度インポートしてもいいのでは?と思いましたが、後からコードを書き足したときに、importの前後でエラーがでたり挙動が変わったりすることがあると言われました。こわい絶対最初に書く。

 で、まずは結果を収納するフォルダを作成するところから。
yumarublog.com
 こちらの記事を見ながら書こうとして、どこに作成するかは決めてあったのですが、ぎゃー自分のPC内のパスの取得方法が分からない。

 あわてて検索しました。知らないことばっかりです。
tcd-theme.com

 さて、これでフォルダが作れるぞー! と思ったのですが、そういえば結果フォルダの名前についてなんか決めてなかったっけ……

  • フォルダ名は「ocr_作業した日時(yymmddhhmmss)」

 ぎゃー!めんどくさい!
 いや決めたのは私なんですけど……勉強になるしと思ってそうしたんですけど……。

 そんなわけでフォルダ名に現在時刻を入れる方法を調べました。 
qiita.com

 datetime.datetime.now()で現在日時を取得して、datetime.strftime()でフォーマットを指定。

#現在時刻を取得
objNOW = datetime.datetime.now()

# 結果フォルダのパスを指定
path='/midoliko/python/results'

# 結果フォルダ名
dir_name = 'ocr_'+objNOW.strftime('%y%m%d_%H%M%S')

 ようやく結果フォルダを作るところが終わりました。これでやっと一行ぶんです。先は長い。

【#06】プログラム完全初心者がPythonを触ってみた(基礎設計の見直し)

 前の記事はこちら。
midoliko-tsuki.hatenablog.com

 テキストを新規作成して結果を書き込むのはできそうな気がする。でも、ディレクトリ内のPDF全部に同じ処理を繰り返している中で、結果のテキストファイルに元のPDFと同じ名前をつけるやり方が分からない。
 ということで、我が家のヘルプデスクこと夫をつかまえて聞いてみました。

夫「混乱してるみたいだから、まず書いてみて」

 こ、混乱なんかしてへんわ!と不満だったのですが、目に見えてないと分かりにくいのは確かなので、順番に書き出してみました。

  1. PDFのフォルダを取得
  2. テキストファイル作成
  3. フォルダから任意のファイルを取得
  4. 画像に変換
  5. OCR
  6. テキストデータに変換する
  7. テキストファイルに保存して閉じる

 というところまで書いて、テキストファイルを保存するフォルダはいつ作ったらいいの?と尋ねたら、「場所を決めないと作れないよ」と言われました。ええっそうなの?でもそうか!

  1. 結果フォルダを作成
  2. PDFのフォルダを取得
  3. 結果フォルダ内にテキストファイル作成
  4. フォルダから任意のファイルを取得
  5. 画像に変換
  6. OCR
  7. テキストデータに変換する
  8. テキストファイルに保存して閉じる

 というところで再度つっこみが。PDFフォルダを取得するだけでは、その中のどのファイルに対して処理を実行していいのか分からない。なのでPDFフォルダのファイル名リストを取得して、順番に実行していく、らしい。「何の順番でとか指定するの?」と聞いてみたら、特に必要なければそこは指定しないでいいらしくて、じゃあフォルダ渡したらそこから適当に処理してくれよー、という気もしますが、コンピュータ相手に駄々をこねても仕方ないので従います。

 で、ファイル名リストを取得するので、ついでにここで取得した文字列を使って、変換後のテキストファイル名にしたらいいよ、と言われました。

  1. 結果フォルダを作成。フォルダ名は「ocr_作業した日時(yymmddhhmmss)」
  2. PDFフォルダのファイル名リストを取得
  3. ファイル名リストからPDFを選び出して変換対象リストを作る
  4. 変換対象リストから変換対象ファイルを選択する
  5. 変換対象ファイルの最後3文字をtxtに置換した文字列を作る
  6. 結果フォルダ内にテキストファイルを新規作成する。ファイル名は前項で作った、変換対象ファイルの最後3文字をtxtに置換した文字列
  7. 画像に変換
  8. OCR
  9. テキストデータに変換する
  10. テキストファイルに保存して閉じる

 PDFだけを選び出してるのでpdfをtxtに置換するんじゃだめなの?と聞いてみたのですが、この場合はやらない方がいいと言われました。置換だと、ファイル名にpdfという文字列があった場合、そこもtxtになってしまうから、だそうです。なるほど、幽遊白書の海藤くんの「あ、ついでに氷も」のやつみたいだ(そうじゃない)。
 
 それはともかく、全体にまだ狐につままれたような気持ちなので、これを実際に書いてみることにしました。

 続きはこちら。
midoliko-tsuki.hatenablog.com