Pythonのライブラリを使って
株のチャートを生成し、比較する動的ページを作成ました。
このページを作るにあたって、出来た事や躓いた事を復習も兼ねてまとめます。
やりたかったこと。
Pythonの機能をブログから使えるようにする。
具体的には
- ブログのページから証券コードや日付を入力する。
- Pythonで株のチャート画像を作成。
- 二つの画像を比較して、似ているか確認。
画像にすれば、異なる日付・金額でも比較出来るって事が狙い。
実装した機能
プログラミング言語を複数使用しています。
コード内で赤文字にしている所は、他言語とのやり取り箇所なので、要注目です。
1.HTMLのformからPHPにpostし、PHP内で変数として使用。
まず、HTML
<form action="https://osotodegohan.com/python/candle.php" method="POST" id="AjaxForm">
<div>基準銘柄コード:<input id="base_company" type="number" name="base"></div>
<div>基準始め日:<input id="base_sdate" type="date" name="base_sdate"></div>
<div>基準終り日:<input id="base_edate" type="date" name="base_edate"></div>
<div>比較銘柄コード:<input id="hikaku_company" type="number" name="hikaku"></div>
<div>比較始め日:<input id="hikaku_sdate" type="date" name="hikaku_sdate"></div>
<div>比較終り日:<input id="hikaku_edate" type="date" name="hikaku_edate"></div>
<input id="serach" type="submit" value="送信">
</form>
<div id="result">「送信」ボタンを押すとここに実行結果が表示されます。</div>
2~7行目のtypeを変える事で、数字だったり、文字だったりと変える事が出来ます。
number:数字。date:日付。などなど。入力したい項目に合わせていく必要があります。
自学の為に、送信ボタンのIDをsearchと替えていますが
このIDをJavaScriptの1行目と揃える必要があります。
次に、PHP
<?php
//echo "base。";
$base = $_POST['base'];
$base_sdate = $_POST['base_sdate'];//文字形式2022-06-03
$base_edate = $_POST['base_edate'];
//echo $base;
//echo "hikaku。";
$hikaku = $_POST['hikaku'];
$hikaku_sdate = $_POST['hikaku_sdate'];
$hikaku_edate = $_POST['hikaku_edate'];
?>
HTMLのname部分が送られてきます。
つまり、HTMLのinputタグのnameの名称と
PHPの$_POST[***];の***が一致させる必要があります。
今回、初めてPHPに触れたので
- 「$」は変数
- 行の最後は「;」
- コメントアウトは「//」
- 「echo」が表示
まずはこれを抑えておかないと
開発が進まないです。
JavaScriptの使用
また、ここではJavaScriptを使用していて、(Ajaxの部分)
そのコードはこのページから拝借しました。
WPでボタンクリックでPHP実行しページ遷移無しでpost送信してJavascriptで結果を表示する方法
下記のJavaScriptコードは、上のサイトのそのままコピーとなります。
$('#AjaxForm').submit(function(event) {
// HTMLでの送信をキャンセル
event.preventDefault();
var $form = $(this);
var $button = $form.find('.submit');
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: $form.serialize(),
timeout: 10000, // 単位はミリ秒
// 送信前
beforeSend: function(xhr, settings) {
// ボタンを無効化し、二重送信を防止
$button.attr('disabled', true);
$("#result").text("")
},
// 応答後
complete: function(xhr, textStatus) {
// ボタンを有効化し、再送信を許可
$button.attr('disabled', false);
},
// 通信成功時の処理
success: function(result, textStatus, xhr) {
// 入力値を初期化
$form[0].reset();
$("#result").append(result);
},
// 通信失敗時の処理
error: function(xhr, textStatus, error) {
alert('エラー暫くたってからお試しください。');
}
});
// …
});
詳細はリンク先を見て頂きたいです。
wordpressのテーマがcocoonであれば、カスタムJavaScriptに書けば使えます。
確かに機能しましたので、大変ありがたい事です。
2.PHPから引数付きでPythonを実行。
これもPHPコード。
PHPによる外部実行です。execの部分がそれです。
- 第一引数は実行コマンド
- 第二引数は外部実行ファイルの結果
- 第三引数は成功・失敗とか数字で入ります。
所々ある「.」は文字結合です。
$value = $param1.' '.$param2.' '.$param3.' '.$param4.' '.$param5.' '.$param6;
$pythonScript = "~/public_html/osotodegohan.com/python/******.cgi";
$cmd = "export LANG=ja_JP.UTF-8;~/.pyenv/versions/anaconda3-2020.02/bin/python"." ".$pythonScript." ".$value ;
exec($cmd,$output,$result);
$cmdで実行コマンドを作っています。
$cmd=「おまじない」;「Pythonのパス」〇「****.py」〇「1」〇「2」〇「3」となるように
〇の部分は半角スペースです。
おまじない部
最初のexportからUTF-8までは日本語でUTF-8形式で といったおまじない的なもの。
私自身は分かっていませんが、
あった方が良いと見かけたのと、動いているのでそのまま残しています。
Pythonのパス部
~(チルダ)がホームパスが入ります。
私はレンタルサーバーのconohawingを使っています。
ssh接続してpipを使うためにanacondaを入れました。
今までは外付けSSDにubuntuを入れて開発していましたので、anacondaが何を担っているのか、正直理解していません。
が、実行コマンドを作るために、実行ファイルのpythonが必要なため入れました。
ファイルのパス部
$pythonScriptがpythonファイルまでのパス
.cgiとなっているのは、参考したページがそうなっていたから。
今となっては拡張子「****.py」のファイルでも実行できることが分かったのですが、
ちゃんと動いているので、そのまま。笑
まぁ、ファイル名をcgiとしても、pythonで実行しているんですがね。
引数部
Pythonに送るデータは半角スペースを入れてつなげていきます。
python側は
import sys
sys.argv[]配列で受け取ります。
sys.argv[1]からが引数受け取り部になります。
result部について
これがくせ者で、成功が0。
私が引っ掛かったのは失敗で2。
参考文献を忘れましたが、2は命令エラー。
つまり、上の$cmdが悪いということです。
レンタルサーバーを使用するので、パスの指定の仕方が分からず
非常に苦労しました。
~(チルダ)を使ったり、正しいと考えられるパスを直打ちして
何度も実行したのを思い出します。
PHPの要所にechoを入れて、どこまで動いているか確認するといった
デバッグ方法で地道にエラー2を解決しました。
python側ではpathlibといった
****.pyまでのpathを見つけるライブラリもあるので
そういったのを駆使するのもバグ消しに大切です。
3.Pythonが画像を作成し、画像を比較。
pythonに関してはこちら
OpenCVとNumPyで2つの画像を比較(完全一致、部分一致の比率)
このサイトをまんま使わせて頂きました。
4.所定のサーバーに保存。
これはほぼパスの指定の仕方が問題です。
大体「no such file or dictionary」で詰まって飽きます。笑
そんなファイルやフォルダはないですよ。と言われるのです。
パスを見直しましょう。
確認の仕方は
パスを変数に代入して、表示させる。
文字表現を見直す。(ダブルコーテーションとシングルコーテーションが混ざっていないか。など)
ひたすら画面とにらめっこです。
5.PHPで演算結果や画像をブログに表示する。
PHPは1アクションで1Postだそうです。
今回実装したのは、演算結果と画像を画面に返す。のが目的になります。
当初、画像処理はこのサイトを見ました。
PHPで画像を表示する3つの方法を現役エンジニアが解説【初心者向け】
ですが!!
PHPのHTMLへの応答ヘッダーもtype:textになります。
なので、画像が必ず文字化けするんです。
ということで、PHPにHTML形式で画像までのパスを表記して
HTMLにtext形式として応答させることになりました。
これに気付くのにも時間がかかり、正直、飽きます。笑
そして、壊れた画像がマークが出てくるので、F12でパスを確認

これです。幾度となくお世話になった。
F12の一番左の矢印のアイコンから、壊れた画像マークをクリックすると
PHPの返したHTML形式の画像パスが探せます。
おまけ レンタルサーバーにPython環境構築編
下のサイトで
ConohawingにPython環境を入れる方法と
実行パス・ファイルパスの書き方を参考にしました。
ただ、2点気になったのが、
『fatal: remote error:
The unauthenticated git protocol on port 9418 is no longer supported.』
なのが出たら、
『git clone git://github.com/yyuu/pyenv.git ~/.pyenv』ではなく
『git clone https://github.com/yyuu/pyenv.git ~/.pyenv』
ということ。
コマンドがありません。と出たら
.bash_profile編集後にコマンドラインから
$ source ~/.bash_profile
として、更新をする必要があります。
うまくいかなかったら、とにかく更新してみるのも大事かと思います。
追記 javascriptからPHPを実行して、サーバサイドのファイルを削除する。
作成したWebアプリを実行すると、サーバにpngファイルが生成されるのですが、
このままでは画像データが増える一方なので、削除する機能を実装しました。
方法は
1.HTMLのformからPHPにpostし、PHP内で変数として使用。
で作ったJavascriptの通信成功時の処理に
サーバの画像データを削除するPHPを入れるだけ。
詳しくは下記記事に書きました。
参考にしたページはこちら。
グラビカ学習帳 様
JavaScriptから引数つきでPHPを実行
最後に
長々と書いた上に、画像少なめと視認性・可読性の悪い記事になりましたが
最後まで見られた方には感謝です。
主に初学者ですが、何か躓き、このページに辿り着き、問題解決になれば嬉しい限りです。
今回の試みで色んな事が学べました。
言語を組み合わせる事でフロントエンド⇔バックエンドのやり取りも学べました。
「F12」の開発ツールもある程度、見れるようになったりもしました。
また、if文など、基本文法も言語によって、多少書き方が異なるので
そういった経験も出来ました。
色々書いたけど、一番躓いたのはパス。
パスの書き方に苦しんだ記憶しかない・・・。
コメント