個人でサイトを作っていくとき、とにかく「金と時間をかけない」のがコツだと思ってます。
もうちょっとやりたいなぁー…と思ったところで、敢えて手を止める感じでしょうか。
そうしないと長続きしないし、Web制作みたいな奥が深い作業を「根性」だけで続けていても、辛いだけです。
さて、ここではサイト制作をラクにしてくれるPythonというプログラムについて書いていきます。
プログラミングも昔はハマりましたねー
ここに置いていくのは私が学生時代に作っていたノートの写しですから、あるいは間違いがあったり、その人の環境次第では動作しないケースもあるでしょう。
可能な限りミスがないよう修正していますが、もし動作しなかったらご容赦ください。
参考サイト: Python公式ドキュメント
当Webサイト作成者は、例示を目的としてマークアップ及びプログラミング例を提供しており、明示または黙示にかかわらず、いかなる責任も負わないものとします。
このページは、説明されているマークアップ及びプログラミング言語、手順を作成およびデバッグするために使用される各種ツールに読者が精通していることを前提にしています。
このページは、特定の機能を説明するのに役立つ可能性がありますが、当Webサイト作成者がこれらの例を変更した上で、特定の要件を満たすために追加の機能を提供したり、システムを構築したりすることはできません。
加えて、この例の手順に従う場合は、読者の各種ファイルを事前にバックアップすることを推奨いたします。
参考サイト: python.org
Pythonは非常に多用途なプログラミング言語で、次のようなカテゴリに分類されると思われます。また、Pythonはサーバーサイドスクリプトとしても広く使用されています。
ウェブ開発だと、いろんなフレームワークを使ったものが人気ですよね。
Djangoは高機能なフルスタックフレームワークで、ウェブアプリケーションの開発に使えます。
管理画面の自動生成、認証機能、ORM(オブジェクトリレーショナルマッピング)などが標準で備わっていますね。
軽量なマイクロフレームワークとしてはFlaskとか。
FastAPIなんかは高速なAPIフレームワークとして有名で、高性能なAPIの開発ができます。
こういったいろんなフレームワークを使うことで、ウェブアプリケーションやAPIの開発が効率的に行えるってことです。
PythonはGuido van Rossum(グイド・ヴァンロッサム)によって作られました。
身近な話題を選んでpythonを語るなら、グイド・ヴァンロッサムがGoogleやDropboxに入社して働いていたのは有名な話です。
Google・Dropboxともにpythonを頻用しており、彼は大いに活躍したそうですよ?
InstagramはバックエンドシステムにDjangoというPythonで実装されたWebフレームワークを使っていることもよく知られていることです。
最近だと機械学習分野でpythonの話はよく聞きますが、私は上述している、主にWeb開発のフレームワーク(Django、Flaskなど)を利用したWebアプリケーションの開発という方向でpythonにはお世話になってきましたね。
まだこのサイトでDjangoやFlaskなどを導入するのは時期早々だと思いますが、いずれはそれらを込みとして作っていく方向性もあるでしょう。
このように、言語の特性というよりも、私の趣味により近いのがpythonであったということなんです。
グイド・ヴァンロッサム本人のブログである The History of Python
がBloggerで作られているのもおもしろいですね。
独自ドメインでもない、プレーンなブログそのままなんです。
Pythonライブラリは、特定の機能やタスクを簡単に実行できるようにするための、コードの集まりみたいな感じでしょうか。
これらのライブラリは、Pythonプログラムにインポートして使えます。
多くのPythonライブラリは有志の開発者やコミュニティによって作成されていて、開発者は自分で一からコードを書く必要がなく、既存のライブラリを利用して効率的に開発を進めることができるってことですね。
例えば、Pillowは画像処理のためのライブラリであり、NumPyは数値計算のためのライブラリです。
これらのライブラリを使うことで、複雑な処理を簡単に実行できるようになります。
デプロイする前にサーバーを立てつつWebページを確認することもあります。
ローカル環境にHTTPサーバーを構築する方法はいろいろありますが、Pythonでやるのが一番ラクだと感じますね。
Web制作をやってる人は既にpythonをインストールしていろんな環境設定をしていることもあります。
もしやっているなら、ここから下のインストールとダウンロードの各項目は飛ばしてよろしいかと思います。
これで、ローカル環境でありつつ、Webサーバーに上げた状態をチェックすることができます。
win+r→cmd でもいいんだけどね。
私はめんどくさくてbatファイルを作っちゃってます。
コマンドプロンプト起動からローカルサーバー起動、そのままブラウザ起動までフルオートでやってくれるやつ。
個人の環境次第でこういうのも良いと思います。
@echo off
cd C:\Users\アレコレ\google cloud\fein-sites-dev1\www
start python -m http.server 8000
timeout /t 5
start "" "http://localhost:8000"
pause
私はこんな感じです。
でもこの手のbatファイルがあんまり多すぎても自分が混乱しちゃいますけどね。
こういうところに来る人なら分かると思うけど、変換元のExcelは綺麗にしておかないとダメですよ。
変にセル結合などをせず、体裁を整えておきます。
手間を除くためにプログラミングで処理をするのですから、tableタグになってから手書きでいろいろ触っていると意味がないのでね。
Excelの表を手作業でチクチクとtableタグに置き換えるなんて…想像もしたくないです。
大変な作業になりますし、ミスも出ると思うんですよね。
あまり機会は多くないけど、ミスを防ぐという意味でも、プログラムで一括処理しちゃってます。
次の2つをインストールします。
pip install pandas openpyxl
上記2つのライブラリがインストールできたら、次のようにスクリプトを書きます。
Excelの表をhtmlにするtable.py
# pandasライブラリをインポート
import pandas as pd
# Excelファイルのパスを指定
excel_file = r'C:\Users\アレコレ\google cloud\web tools\office\表好きのための表.xlsx'
# Excelファイルを読み込み、データフレームに変換
df = pd.read_excel(excel_file)
# データフレームをHTMLテーブルに変換
html_table = df.to_html()
# HTMLテーブルの出力先ファイルを指定
output_file = r'C:\Users\アレコレ\google cloud\web tools\office\table.html'
# 指定したファイルにHTMLテーブルを書き込む
with open(output_file, 'w', encoding='utf-8') as file:
file.write(html_table)
# HTMLテーブルの作成完了メッセージを出力
print(f"HTMLテーブルが作成されました: {output_file}")
このスクリプトに関しては構造も複雑じゃないから、1行ずつ説明しないけど、丁寧にコメントアウトを付けさせていただきました。
ライブラリの機能を使って変換しているだけです。
スマホでもまともに表示させるために、表の列に関しては多くても3列までとしていますね。
人によってやり方は違うでしょうけど、パソコンを使っていても横に長い表は扱いにくいです。
あと、過度に縦に伸びないように工夫もしています。
表というのは視覚的に構造が分かりやすいから、何かと用いられることが多いレイアウトです。
でも、モバイル表示という観点から言うなら、あまり望ましくない、ないしはできれば避けたいと考えていますね。
単純な2列の表であっても文節が折り返されて読みにくいことがある。
まずは手軽なPDFファイルの操作からいきますか。
必要なのは次の4つです。
これらをまとめてインストールしちゃいます。
次のようにコマンドプロンプトへ入力します。
pip install pymupdf pikepdf pdf2image pytesseract
このコマンドを実行すると、上記4つのPythonパッケージがインストールされます。
これらのパッケージを使うことで、PDFや画像ファイルの操作やテキスト抽出が簡単に行えるようになります。
これもコマンドプロンプトでやれないことはないけど、一発ではないからね。
追加で説明書きたいこともあるから、GUIベースで行きましょう。
簡単な事前説明
Popplerのバイナリは、PDFファイルを操作するためのコマンドラインツールです。
Poppler自体は、PDFのレンダリングライブラリであり、xpdf-3.0コードベースに基づいています。
バイナリとは、ソースコードをコンパイルして生成された実行可能ファイルのことですね。
Popplerのバイナリを使用すると、PDFの変換、結合、抽出などの操作をコマンドラインから実行できます。
例えば、Windows環境では、コマンドプロンプトを開いて「pdfinfo」や「pdftotext」などのコマンドを実行することで、PDFの情報を取得したり、テキストを抽出したりすることができます。
Popplerのバイナリは公式サイトから直接ダウンロードすることはできませんが、GitHubなどのリポジトリから入手することができます。
PopplerはPythonと密接に関連しています。
「python-poppler」というライブラリがあり、これはPopplerのC++ライブラリであるpoppler-cppのPythonバインディングです。─
バインディングというのは「つなぎ役」と捉えてもらえれば良いですね ─
これを使ってPythonからPDFドキュメントを読み込み、レンダリングし、または修正することができます。─ レンダリングというのは「表示」と考えてください ─
例えば、上でお話ししたpdf2imageというPythonモジュールは、PDFを画像に変換する際にPopplerを使用します。
このモジュールを使うことで、PDFページを画像として抽出することが可能となるわけです。
参考サイト:
では、ダウンロードとインストールへ進みます。
ご案内するのは2024年10月現在の確認状況ですから、時間が経っているようであれば都度読み替えてください。
1.Popplerのバイナリをダウンロード
2.ZIPファイルを解凍
3.環境変数に追加
4.動作確認
pdfinfo -v
コマンドプロンプトを再起動しないとpdfinfo -vが正常に動作しない理由は、環境変数の変更が現在のセッションに反映されないためです。
環境変数を設定または変更した場合、その変更は新しいコマンドプロンプトセッションにのみ適用されます。
既存のセッションでは変更前の環境変数が引き続き使用されるため、再起動が必要となります。
ちょっとめんどうですが、初期の環境設定ですから。
コマンドプロンプトを再起動すれば新しい環境変数の設定が反映され、pdfinfo -vが正常に動作するようになります。
正常にインストールされていれば、popplerのバージョン情報が表示されます。
これでpopplerがインストールされ、環境変数に追加されたことになります。
環境変数とは、オペレーティングシステムやアプリケーションが動作する際に使用する設定情報を格納するための変数です。
これらの変数は、システム全体や特定のユーザーの設定を定義するために使用されます。
例えば、環境変数には次のようなものがありますね。
環境変数は、システムの動作やアプリケーションの設定に大きな影響を与えるため、丁寧に作業することが必要です。
Pythonでの環境変数は、プログラムの実行時に外部から設定される変数で、プログラムの動作に影響を与える設定情報を提供します。
ここで、上記でPopplerをインストールした後に環境変数に追加する手順を踏んでいるのは、システムや他のアプリケーションがPopplerの実行ファイルやライブラリにアクセスできるようにするためです。
具体的な理由としては、次のようなものがあります。
Windowsの場合、LD_LIBRARY_PATHのような環境変数は使用しません。その代わりに、PATH環境変数にPopplerの実行ファイルやライブラリのパスを追加します。
これでシステムやアプリケーションがPopplerの実行ファイルやライブラリにアクセスできるようになります。
上記手順は、Popplerをインストールしたディレクトリを確認して環境変数の設定を行うという作業なんです。
PythonのTesseractは、正式にはpytesseractと呼ばれます。
このライブラリはPythonで使用できる光学文字認識(OCR)ツールです。
GoogleのTesseract-OCRエンジンのラッパーであり、画像に埋め込まれたテキストを認識して「読み取る」ことができます。
ラッパーという表現について、少し詳しくお話ししようかな…
ここで言う「GoogleのTesseract-OCRエンジンのラッパー」というのは、Tesseract-OCRエンジンをPythonなどのプログラミング言語から簡単に利用できるようにするためのインターフェースを提供するものなんだという意味です。
Tesseract-OCRエンジンの機能を呼び出すためのコードを簡略化し、使いやすくするためのPythonライブラリが「pytesseract」、すなわち今からインストールしようとしているTesseractとなります。
Tesseract-OCRエンジン自体は、画像からテキストを抽出するツールなのですが、直接使うにはコマンドライン操作や複雑な設定が必要になることがあります。
pytesseractは、これらの操作をPythonコード内で簡単に行えるようにするためのラッパーということです。
では、ダウンロードとインストールへ進みます。
ご案内するのは2024年10月現在の確認状況ですから、時間が経っているようであれば都度読み替えてください。
1.Tesseractのインストール
2.環境変数に追加
ここは、上述の「Popplerのバイナリをインストール」した時と同じです。でもササっと手順を書いておきます。
3.動作確認
tesseract -v
正常にインストールされていれば、Tesseractのバージョン情報が表示されます。
これでTesseractがインストールされ、環境変数に追加されたことになります。
ここまでは環境が整っている人が多いかな?
そろそろ具体的なpythonスクリプトに話題を移していきます。
あんまり深入りすると大変ですからね。
あくまでも当初の目的である「Webサイト制作でラクをする」という側面を大切にしていきましょう。
まず、次のコードを見てみましょう。
ファイル名は「pdf.py」という名で保存されているものです。
PDFをまとめて圧縮するpdf.py
import pikepdf
import os
def compress_pdf(input_path, output_path):
try:
with pikepdf.open(input_path) as pdf:
pdf.save(output_path)
except Exception as e:
print(f"Error compressing {input_path}: {e}")
def compress_pdfs_in_directory(input_dir, output_dir):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for filename in os.listdir(input_dir):
if filename.endswith(".pdf"):
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
compress_pdf(input_path, output_path)
input_directory = r"C:/Users/アレコレ/google cloud/fein-sites-dev1/www/another-eden/fein_report"
output_directory = r"C:/Users/アレコレ/Documents/pdf"
compress_pdfs_in_directory(input_directory, output_directory)
それぞれを簡単に説明していきます。
このコードは指定されたディレクトリ内のPDFファイルを圧縮し、別のディレクトリに保存する一連の処理を行っています。
import pikepdf
PDFファイルを操作するためのライブラリ pikepdf をインポートしています。
import os
ファイルやディレクトリの操作を行うための標準ライブラリ os をインポートしています。
def compress_pdf(input_path, output_path):
ここでは、PDFファイルを圧縮する関数 compress_pdf を定義しています。
この関数は、入力ファイルのパスと出力ファイルのパスを引数に取ります。
try:
ここから、エラーが発生する可能性のある処理となります。
with pikepdf.open(input_path) as pdf:
指定されたパスのPDFファイルを開きます。
with文を使うことで、ファイルを自動的に閉じることができます。
pdf.save(output_path)
開いたPDFファイルを指定された出力パスに保存します。
except Exception as e:
もしエラーが発生した場合、このブロックが実行されます。
print(f"Error compressing {input_path}: {e}")
エラーが発生した場合、そのエラーメッセージを表示します。
def compress_pdfs_in_directory(input_dir, output_dir):
ここでは、ディレクトリ内のすべてのPDFファイルを圧縮する関数 compress_pdfs_in_directory を定義しています。
この関数は、入力ディレクトリと出力ディレクトリを引数に取ります。
if not os.path.exists(output_dir):
出力ディレクトリが存在しない場合をチェックします。
os.makedirs(output_dir)
出力ディレクトリが存在しない場合、新しく作成します。
for filename in os.listdir(input_dir):
入力ディレクトリ内のすべてのファイルをループで処理します。
if filename.endswith(".pdf"):
ファイル名が「.pdf」で終わる場合のみ処理を行います。
input_path = os.path.join(input_dir, filename)
入力ファイルのフルパスを作成します。
output_path = os.path.join(output_dir, filename)
出力ファイルのフルパスを作成します。
compress_pdf(input_path, output_path)
先ほど定義した compress_pdf 関数を使って、PDFファイルを圧縮します。
input_directory = r"C:/Users/アレコレ/google
cloud/fein-sites-dev1/www/another-eden/fein_report"
圧縮するPDFファイルが保存されているディレクトリのパスを指定します。
output_directory = r"C:/Users/アレコレ/Documents/pdf"
圧縮されたPDFファイルを保存するディレクトリのパスを指定します。
compress_pdfs_in_directory(input_directory, output_directory)
指定されたディレクトリ内のPDFファイルを圧縮する処理を実行します。
このコードのポイント
コードの概要
このコードの対応関係
input_path と output_path
compress_pdf 関数内で使用され、個々のPDFファイルの入力パスと出力パスを指定します。
例:input_path が C:/Users/アレコレ/google cloud/fein-sites-dev1/www/another-eden/fein_report/sample.pdf
で、output_path が C:/Users/アレコレ/Documents/pdf/sample.pdf になります。
input_directory と output_directory
compress_pdfs_in_directory 関数内で使用され、ディレクトリ全体の入力パスと出力パスを指定します。
例:input_directory が C:/Users/アレコレ/google cloud/fein-sites-dev1/www/another-eden/fein_report
で、output_directory が C:/Users/アレコレ/Documents/pdf になります。
このコードのポイント
def はPythonで関数を定義するためのキーワードです。
関数は特定のタスクを実行するためのコードのブロックで、再利用可能な形でまとめられています。
とりあえず def を使って関数を定義する基本的な構文から。
def 関数名(引数1, 引数2, ...):
# 関数の処理内容
return 戻り値
例えば…足し算する関数を定義する場合です。
def add_numbers(a, b):
result = a + b
return result
この関数 add_numbers は、引数 a と b を受け取り、それらを足し合わせた結果を返します。
ここで紹介しているPDF圧縮プログラムの場合
次のように def を使って関数を定義しています。
このように関数を使うことで、コードを整理し、再利用可能にすることができます。
def はPythonで関数を定義するために必ず使用しなければならないキーワードです。
これはPythonの構文の一部であり、他の言葉に置き換えることはできません。
プログラミング言語にはそれぞれのルールや構文があり、Pythonでは関数を定義するために def を使うと決められています。
例えば、他のプログラミング言語では異なるキーワードを使いますが、それぞれの言語のルールに従う必要があります。
もし def を別の言葉に置き換えようとすると、Pythonはエラーを出してしまいます。
ここで、正しい使い方と間違った使い方の例です。
def my_function(): # 正しい使い方です
print("Hello, World!")
define my_function(): # これはエラーになります
print("Hello, World!")
プログラミング言語の構文を守ることで、コードが正しく動作し、他のプログラマーとも共有しやすくなります。
with はPythonでリソースの管理を簡単にするためのキーワードです。
特にファイルの操作やネットワーク接続など、リソースの解放が必要な処理でよく使われます。
with を使うことで、リソースの解放も自動的に行うことができます。
基本的な使い方を挙げてみます。
with を使ってファイルを開く例です。
with open('example.txt', 'r') as file:
content = file.read()
print(content)
このコードは、Pythonでファイルを読み込んでその内容を表示するものです。
実行すると、次のように動作します。
このコードを実行すると、example.txt ファイルの中身がそのままコンソールに出力されます。
例えば、example.txt に「Hello, World!」と書かれていた場合、実行結果はそのまんま「Hello, World!」となりますね。
with の役割
ここで紹介しているPDF圧縮プログラムの場合
次のように with を使ってPDFファイルを開いています。
with pikepdf.open(input_path) as pdf:
pdf.save(output_path)
この部分では、input_path からPDFファイルを開き、output_path に保存しています。
with を使うことで、PDFファイルが自動的に閉じられ、リソースが適切に解放されています。
仕上げに、丁寧にコメントアウトが書かれたpythonコードを置いておきましょう。
# pikepdfとosモジュールをインポート
import pikepdf
import os
# PDFファイルを圧縮する関数
def compress_pdf(input_path, output_path):
try:
# 入力ファイルを開く
with pikepdf.open(input_path) as pdf:
# 出力ファイルとして保存
pdf.save(output_path)
except Exception as e:
# エラーが発生した場合のメッセージを表示
print(f"{input_path}の圧縮中にエラーが発生しました: {e}")
# ディレクトリ内のすべてのPDFファイルを圧縮する関数
def compress_pdfs_in_directory(input_dir, output_dir):
# 出力ディレクトリが存在しない場合は作成
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 入力ディレクトリ内のすべてのファイルをループ
for filename in os.listdir(input_dir):
# PDFファイルのみを対象
if filename.endswith(".pdf"):
# 入力ファイルと出力ファイルのパスを作成
input_path = os.path.join(input_dir, filename)
output_path = os.path.join(output_dir, filename)
# PDFファイルを圧縮
compress_pdf(input_path, output_path)
# 入力ディレクトリのパス
input_directory = r"C:/Users/アレコレ/google cloud/fein-sites-dev1/www/another-eden/fein_report"
# 出力ディレクトリのパス
output_directory = r"C:/Users/アレコレ/Documents/pdf"
# ディレクトリ内のPDFファイルを圧縮
compress_pdfs_in_directory(input_directory, output_directory)
これは昔から使用頻度が極めて高かったです。
スクリプトとしては単純ですが、重要なのはその使い道にあると思います。
html+css+JavaScriptだけだと、どうしても細かいレイアウトやいかにも文書レポートらしい味わいが出ないことがあります。
やれないことはないけど、手間に見合わない。
そういう時、次のような流れを踏むと、Webサイトに掲載する凝った文書レポートを簡単に作成できます。
こうすると、単に画像を貼るだけより目を引くコンテンツをWebサイトへ掲載できます。
PDF専用の枠組みやUIを用意して掲示すれば、専用文書みたいなムードが出るんですよね。
PDFを高解像度の画像に変換するpdfimg.py
from pdf2image import convert_from_path # pdf2imageライブラリから、convert_from_path関数をインポート
pdf_path = r'C:\UsersアレコレOneDrive\_fein\google cloud\web tools\20241019サイト更新案内.pdf' # 処理するPDFファイルのパスを指定
images = convert_from_path(pdf_path, dpi=300) # PDFファイルを300dpiの解像度で画像に変換
for i, image in enumerate(images): # 各画像をループして処理
image.save(f'output_image_{i + 1}.png', 'PNG') # 画像をPNG形式で保存
このスクリプトは指定されたPDFファイルを読み込み、そのPDFの各ページを画像に変換し、それぞれの画像をPNG形式で保存するものです。
pdf2imageライブラリのconvert_from_path関数を使って、PDFファイルを画像に変換します。
変換された画像はリストとして返され、forループを使って各画像を処理し、ファイル名にページ番号を付けてPNG形式で保存しています。
保存される画像ファイルの名前はoutput_image_1.png、output_image_2.pngというように、ページごとに異なる名前になります。
学生時代のスクリプトだからちょっと曖昧な部分もあるのですが、pdf2imageライブラリが動作するためには、PyMuPDF または Poppler のいずれかが必要だったはずです。
pdf2imageライブラリと併せて、せっかくなので両方とも紹介しましょう。
pdf2imageライブラリはPython用のライブラリで、PDFファイルの各ページを画像に変換するためのツールです。
これを使うと、PDFの内容をプログラム的に画像ファイルとして取り扱うことができるようになります。
例えば、PDFの各ページをJPEGやPNG形式の画像に変換して保存することが可能です。
このライブラリは、PyMuPDFやPopplerなどのバックエンドを使用して、PDFファイルから画像を抽出します。
次のコードでpdf2imageがインストールされます。
pipはPythonのパッケージマネージャですね。
pdf2imageのインストール
pip install pdf2image
pdf2imageライブラリは単独でPDFから画像を抽出できるわけではなく、他のプログラム(バックエンド)を利用してその機能を実現しています。
そのバックエンドというのが、PyMuPDF または Poppler のどちらか一つなんですよね。
そう、なので…スクリプトによってはどちらか1つでも良かったはずです。
PyMuPDFのインストール
これは特にややこしいことはないです。
Windowsなら次のコマンドでOK。
pip install pymupdf
Popplerのインストール手順(Windows)
Windowsではpopplerを直接インストールするのではなく、バイナリをダウンロードしてパスを通す必要があります。
これで、Popplerが正しくインストールされ、パスが通った状態になります。
Popplerのインストール手順(Linux)
私はDebian系のUbuntuを使ってたから、そっちのパッケージマネージャーを使用したインストール方法を書きましょうか。Debian系でPopplerのインストール
sudo apt-get update
sudo apt-get install poppler-utils
こういうところを見ると、やはりWindowsよりLinuxのほうが個人サイトは作りやすいと思います。
そこらへんのウェブサイトビルダーを使うならWindowsでも良いですが、コードを全て書くことで完全オリジナルな個人サイトを作ろうとしたとき、慣れた人ならともかく、そうでないと環境構築に手間がかかる。
Linuxのほうが手順が単純です。
アナザーエデン:feinが書いたレポート集にあるPDFの数々は、こうやって画像化してからTweetしていたのです。
Twitterでは無料で画像化してくれるWebサービスを紹介しておりましたが、実際の私の手元ではpythonスクリプトで処理していました。
周りを見ると、あまりプログラミングをやるような人が見られなかったこともありますね。
アカウントから出るコンテンツの作成過程については、たとえこのスクリプトのような簡単なことであったとしても、あまり大っぴらにしない方がいい。
イーロンマスクの話ではないけど、SNSはどこも対抗意識や競争意識の魔窟です。
全てが終わってから表に出す方が、SNSアカウントの話題コントロールもやりやすいってことよね。
でも、もうこうして生コードの個人サイトも公開しており、アナデンの高難易度バトルについてPDFレポートを作成する必要もなくなったから。
このスクリプトは学生時代からずっと大活躍していたのですよ?
このスクリプトはPDFファイルが既にテキストベースかどうか、まとめてチェックします。
画像からテキストを抽出できるかを確認することで、OCR処理が可能かどうかを判断するんです。
小さなことですが、Webサイトに大量のPDFがある場合、それらも検索エンジンに載せる必要があります。
この時、PDFがテキストベースでなければほとんど意味を成しません。
例えばマニアックな魚の生態などを調べていると、どこかの大学が書いた論文等がたくさん出てきますよ。
検索ワードの組み合わせによって出てくることもあるし、手持ち資料にPDFがあるなら、それらもしっかりWebサイトに載せておくと時間をかけて効いてきます。
PDFがテキストベースになっているかチェックするpdfocr.py
import os
import fitz # PyMuPDFライブラリをインポート
import pytesseract # OCRライブラリをインポート
from pdf2image import convert_from_path # PDFを画像に変換するライブラリをインポート
# PDFがテキストベースかどうかを確認する関数
def is_text_based_pdf(pdf_path):
try:
# PDFドキュメントを開く
pdf_document = fitz.open(pdf_path)
# 各ページをチェック
for page_num in range(len(pdf_document)):
page = pdf_document.load_page(page_num)
text = page.get_text()
# テキストが含まれている場合はTrueを返す
if text.strip():
return True
# テキストが含まれていない場合はFalseを返す
return False
except Exception as e:
# エラーが発生した場合の処理
print(f"エラーが発生しました: {e}")
return False
# OCRが可能かどうかを確認する関数
def is_ocr_possible(pdf_path):
# PDFがテキストベースの場合はTrueを返す
if is_text_based_pdf(pdf_path):
return True
try:
# PDFドキュメントを開く
pdf_document = fitz.open(pdf_path)
# 各ページをチェック
for page_num in range(len(pdf_document)):
page = pdf_document.load_page(page_num)
# ページを画像に変換
pix = page.get_pixmap()
image = convert_from_path(pdf_path, first_page=page_num+1, last_page=page_num+1)[0]
# 画像からテキストを抽出
text = pytesseract.image_to_string(image)
# テキストが含まれている場合はTrueを返す
if text.strip():
return True
# テキストが含まれていない場合はFalseを返す
return False
except Exception as e:
# エラーが発生した場合の処理
print(f"エラーが発生しました: {e}")
return False
# ディレクトリ内のPDFファイルをチェックしてOCRが可能かどうかを確認する関数
def check_directory_for_ocr(directory_path):
# ディレクトリ内のPDFファイルをリストアップ
pdf_files = [f for f in os.listdir(directory_path) if f.lower().endswith('.pdf')]
results = {}
# 各PDFファイルをチェック
for pdf_file in pdf_files:
pdf_path = os.path.join(directory_path, pdf_file)
results[pdf_file] = is_ocr_possible(pdf_path)
return results
# 使用例
directory_path = r"C:\Users\アレコレ\Downloads\drive-download"
ocr_results = check_directory_for_ocr(directory_path)
# 各PDFファイルのOCR可能性を表示
for pdf_file, is_ocrable in ocr_results.items():
print(f"{pdf_file}: {'OCR可能' if is_ocrable else 'OCR不可能'}")
このスクリプトは、指定されたディレクトリ内のPDFファイルがOCR(光学文字認識)可能かどうかをチェックしています。
OCRのライブラリについては、このページの上部ですでに触れましたね。
必要なライブラリのインポート
使用例
チェックするディレクトリのパスを指定します。
check_directory_for_ocr 関数を呼び出し、結果を取得します。
各PDFファイルのOCR可能性を表示します。
ちょっと分かりにくいかもしれないので、改めて該当部分を書いてみます。
# 使用例
directory_path = r"C:\Users\アレコレ\Downloads\drive-download"
ocr_results = check_directory_for_ocr(directory_path)
# 各PDFファイルのOCR可能性を表示
for pdf_file, is_ocrable in ocr_results.items():
print(f"{pdf_file}: {'OCR可能' if is_ocrable else 'OCR不可能'}")
この「# 使用例」の部分は、単なる説明文ではなく、スクリプトの実行例を示す重要な部分です。
この部分がなければ、スクリプトは実際に動作しません。
関数がどのように動作するかを確認することができませんし、スクリプト全体の動作をテストすることもできません。
つまり、「# 使用例」の部分は、スクリプトの動作を確認するための実行例であり、スクリプトの一部として重要な役割を果たしています。
この部分では、次のように動作しています。
このように、「# 使用例」は、スクリプトの機能を実際にどのように使うかを示すための例として書かれています。
あるいは実行例とか、サンプルコードといった用語でも良いかもしれない。
いずれにしても、これで全てのPDFがOCR可能であることを確認してから、このサイトではPDFを掲載しています。
でももともとWordやExcelで書いたレポートをPDF化しているだけですから、まず問題が出ることはないでしょう。
例えば report.html というページがあるとしましょう。
そのhtmlファイルがある場所に「pdf」というディレクトリがあります。
そのpdfディレクトリに大量のpdfが格納されている。
この状況で、report.htmlにpdfファイルへのハイパーリンクを記述していくのは大変な作業となります。
5つや6つくらいならともかく、100を超えてくると人力では難しいでしょう。
ハイパーリンクというのは <a href=""></a> と書かれます。
report.htmlに記述されるpdfファイルへのハイパーリンクは当然 <a href="pdf/explanation.pdf"></a>
となりますが、大量にあるファイルへのハイパーリンクの記述を延々と手書きしていると、必ずと言って良いほどミスに繋がるんです。
あまり好きな表現ではないのですが、いわゆる「個人サイト臭さ」というのは、こういうところから出てきます。
たまに1つや2つのミスが見つかるくらいなら許容できるし、むしろ可愛げさえ出てくる。
しかし…どこのページに行っても、いつ見ても何かしらミスがあったり、中途半端だったり。
これが続くと、人はそのWebサイトに訪問しなくなります。
使いにくいことが分かっているからね。
悪印象が定着してしまうのです。
ここで紹介するスクリプトは、人間の手作業によるケアレスミスを防ぐためのスクリプトです。
どんなに工夫してもミスをゼロにすることはできませんが、やれることはやったほうが良いですね。
大量のハイパーリンクをまとめて記述するpdfhtml.py
import os # osモジュールをインポートして、ファイルやディレクトリの操作を行う
# PDFファイルが保存されているディレクトリのパスを指定
directory = r'C:\Users\アレコレ\OneDrive\_fein\google cloud\fein-sites-dev1\www\another-eden\fein_report'
# HTMLファイルの出力先のパスを指定
output_file = r'C:\Users\アレコレ\OneDrive\_fein\google cloud\web tools\pdfhtml.html'
# HTMLファイルを作成して書き込みモードで開く
with open(output_file, 'w', encoding='utf-8') as f:
f.write('<html><body>\n') # HTMLファイルの基本構造を作成
# 指定したディレクトリ内のすべてのファイルをループで処理
for filename in os.listdir(directory):
print(f'Found file: {filename}') # デバッグ用にファイル名をコンソールに表示
if filename.endswith('.pdf'): # ファイル名が.pdfで終わる場合
# HTMLリンクを作成してファイルに書き込む
f.write(f'<p><a href="fein_report/{filename}">{filename}</a></p>\n')
f.write('</body></html>') # HTMLファイルの終了タグを追加
print(f'HTML file has been created: {output_file}') # 完了メッセージをコンソールに表示
このコードは、指定されたディレクトリ内のすべてのPDFファイルをリスト化し、それらのファイルへのリンクを含むhtmlファイルを生成します。
なんでhtmlファイルを生成するかというと、そのまんまコピペできるからですよ。
pythonにhtmlコードを書かせるだけ書かせて、自分はコピペするだけです。
こういう小さなミスを防げるスクリプトを書けると、格段に個人サイト作成がラクになりますよ?
何百回も似たような作業をしていれば必ずミスは発生するのですから、とりあえず自動化できる部分は自動化しちゃった方がいいよね。
とにかくラクをして金もかけないこと。
これが個人サイトを継続するために必要な、最も重要なポイントであるとみて間違いないです。
大変な思いをするから放置しちゃう。
そこをプログラミングで何とかするっていう。
当サイトでは、PDFを気軽に閲覧できるようプレビューボタンを設置しています。
通常のハイパーリンク以外にボタンを設置しており、そこを押すとPDFがプレビュー表示できます。
この機能があればいちいちWebサイトから外部のアプリに出ずとも、そのままブラウザでPDFファイルの中身を閲覧できるからです。
JavaScriptとCSSに関しては 個人サイトでよく使うJavaScript で説明しています。
ここではpythonによるhtmlコード出力について、説明します。
このPDFプレビューボタンが、けっこう手間のかかるコードなんですよねー
CSSはともかくJavaScriptでページ送りやらページ数やらを制御していることもあって、それらのボタンまでhtmlで作ってあげないといけない。
見た目は単なるボタンだけどコードがちょっと長いので、複数のPDFを扱うと非常に面倒です。
そこで、pythonに作ってもらうんだよね。
やっていることは単純です。
ワンパターンなhtmlコードがあり、そこにpdfファイルを当てはめていくだけのお仕事をpythonにやってもらいます。
こういう作業が人間が100回200回とやっていくと、ミスに繋がるわけですよ。
実際のpythonスクリプトに入る前に、Webページに載せる予定のpdfファイルリストを用意します。
ファイル名と拡張子だけを抽出するコマンド
dir /b "C:\path\to\directory" > filelist.txt
このコマンドをコマンドプロンプトで実行すれば、ある任意のディレクトリに格納されているファイルの名称と拡張子だけを抽出できます。
こんなの手作業でやってたらキリないですよ。
実際にはこの作業もpythonにやってもらうことができますが、私の環境ではpdfファイル以外にいろいろ入っていたものでね。
いきなりhtmlを書く前に少し確認することにしたのです。
取得したpdfファイル名と拡張子のリストを使って、次のようなスクリプトを用意します。
PDFプレビューボタンhtmlを書くpdfpreview.py
# PDFファイル名称リスト
pdf_files = [
"高難易度対策ノート:最終更新=20210404.pdf",
"魚のさばき方.pdf",
"黒衣の刀使いの影.pdf",
"2部結戦役.pdf",
"3部直前アナデンプレイ状況アンケート結果.pdf"
]
# HTMLテンプレート
html_template = """
<div class="pdf-list-add">
<button class="pdf-link-add" data-url="fein_report/{0}">{0}を開く</button>
</div>
<div class="feinpdf-container-add addpdfhidden">
<div class="feinpdf-viewer-add"></div>
<div class="feinpdfcontrols-add">
<button class="prev-page-add">前のページへ</button>
<span>Page: <span class="page-num-add"></span> / <span class="page-count-add"></span></span>
<button class="next-page-add">次のページへ</button>
</div>
</div>
"""
# HTMLファイルに出力
# "output.html" という名前のファイルを作成し、書き込みモードで開きます
with open("output.html", "w", encoding="utf-8") as f:
# PDFファイルリストの各ファイル名についてループします
for pdf in pdf_files:
# HTMLテンプレートにPDFファイル名を挿入し、ファイルに書き込みます
f.write(html_template.format(pdf))
このスクリプトは指定されたPDFファイル名を使ってHTMLボタンを生成し、それを output.html ファイルに書き出すものです。
大量のpdf資料があっても、このスクリプトを使えば一気にWebサイトへ掲載できるのですよ。
officeソフトで作られた文書類をwebサイトに掲載するなら、pdfにしてからプレビュー機能付きでハイパーリンクを添えるのが一番無難だと思います。
アナザーエデンの強敵戦やストーリーコンテンツのリスト、お勧めバッジなどを掲載したコーナーです。
期間限定のない普通のRPGですので、初心者でも安心して続けていけるゲームとなっています。
もっとも重要なグラスタについては、場所別に網羅した表があります。
個人でウェブサイトを作るにはどうすればいいか。
HTML・CSS・JavaScriptの書き方はもちろん、無料かつ広告なしでホームページを作る方法を掲載したコーナーです。
Webデザインやレイアウトについても書いてあります。
ゲームとパソコンだけじゃなく、アウトドアも趣味なんです。
このコーナーでは魚釣りの記録とか、魚料理のレシピ、はたまたサイクリングなどなど。
アウトドアに関連するコンテンツが詰め込まれています。