cytoscape.js のはてなブログへの埋め込みテスト

準備(設定)

下記行をブログタイトル下に埋め込む

    <title>Learning Cytoscape.js</title>
    <style type="text/css">
        /* cytoscape graph */
        #cy {
            height: 300px;
            width: 400px;
            background-color: #f9f9f9;
        }
    </style>

  <script src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"></script>
  <script src="https://unpkg.com/cytoscape@3.8.1/dist/cytoscape.min.js"></script>

具体的には、はてなブログの「設定」→「カスタマイズ」→「ヘッダ」で下記のように行う。

cytoscape.js をはてなブログで使うための設定

テスト

記事中に下記行をいれる。<script>タグの前にスペースを入れないこと。

<script>


$(function(){
  //内容要素はJSONオブジェクトである、サーバ側加工しフロントに渡すもの
  var elements = {
      nodes:[
          //グラフの点、ノードのidが必須で、他の属性は機能によって調整するばよい
          {data: {id: '172', name: 'Tom Cruise', label: 'Person'}},
          {data: {id: '183', title: 'Top Gun', label: 'Movie'}}
      ],
      edges:[
          //グラフの線、エッジはsource(開始点id)とtarget(終了点id)は必須で、他の属性も追加可能
          {data: {source: '172', target: '183', relationship: 'Acted_In'}}
      ],
  }

  //内容要素を表現するCSS
  var style = [
      //セレクターで拾いた内容要素が 指定したCSSを適用する
      //ノードの中で、label属性は「Peson」のノードが青色で表示し、文字はname属性を表示する
      { selector: 'node[label = "Person"]', 
        css: {'background-color': '#6FB1FC', 'content': 'data(name)'}
      },
      //ノードの中で、label属性は「Movie」のノードがオレンジ色で表示し、文字はtitle属性を表示する
      { selector: 'node[label = "Movie"]', 
        css: {'background-color': '#F5A45D', 'content': 'data(title)'}
      },
      //エッジ全体で、文字はrelationship属性を表示する、終了点での矢印は三角形にする
      { selector: 'edge', 
        css: {'content': 'data(relationship)', 'target-arrow-shape': 'triangle'}
      } 
  ]


  // Cytoscapeオブジェクト初期化。
  var cy = cytoscape({ 
    // containerがHTML内の「cy」DOM要素に指定
    container: document.getElementById('cy'),
    elements: elements,
    style: style

  });
});

</script>
<div id="cy"></div>

すると下記のように表示される。

感想

ノードのデフォルトスタイルである <style> タグ記述をブログの設定(すべてのブログ記事に適用される)で書かないといけないのは厳しいなあ。

スマホからメールでウェブ予約するシステムをRPA(selenium)で1日で作った話

TL;DR

  • よくあるウェブ画面でクリックして予約する操作を RPA で自動化しました。
  • スマホから予約情報をサブジェクトに入れて自分宛てにメール送信すると予約できます。
  • 子供のスマホのブラウザアプリに使用制限をかけたい人におすすめ!

経緯

ある土曜、娘が「スマホの使用時間制限のせいでよく行く音楽練習室のウェブ予約が夕方出来なくなるからなんとかしてー」と云ってきました。 娘のスマホにはiOS12 のスクリーンタイムで使用制限をかけています。アプリ単位で使用時間を制限できるので、通話やメール、LINEは24 時間OK, YouTube やゲームは1日2時間のような制限をかけています。ところがブラウザアプリ(safari) は使用制限の指定が難しく、上記のような予約や学校関連の連絡・事務手続きは24H 許可したいものの、そうするとブラウザ経由で youtube が24 H 見れてしまいます。 予約なら前の日に自宅のPCからしろと言いたいところですが、音楽練習室の事情で予約したい時間(娘の場合平日18時以降)の1時間前にならないと予約出来ません。 そこで、勉強がてらウェブのサイトにアクセスして予約するスマホアプリを作ろうと思い立ちました。これがあればブラウザアプリを使わずに予約できます。

「よっしゃ父ちゃんがスマホアプリ作っちゃる。次いつ行くの?」 「月曜から使いたい!」・・・ガーン(古!)

アプリ開発環境の勉強*1から始めて1日でとりあえず動くものを完成させるのはさすがにきつい。。。そこでスマホアプリは諦め、スマホからウェブ予約できるものをとにかく「1日で作る」ことを最優先して出来上がった代物が下記です。 selenium 使っただけで"RPA" と呼べるか微妙ですが、大目に見て下さい😅

動作環境

  • メールアカウント(POP接続できるもの)
  • サーバ( python コードが実行でき 24H インターネット接続環境であれば何でも)
  • python3
  • selenium(chromedriver)
  • Katalon Recorder (chrome extension )

Katalon Redcorder はブラウザ操作を記録して、それを pythonselenium モジュール用のコードとして出力するものです。コード中のHTML要素の指定の仕方(Xpath) がイマイチですが、無い場合に比べると大変省力化できます。インターネット上に紹介記事がいろいろありますのでここでは触れません。 Katalon Recoder をONにした状態で実際にウェブ画面を操作して予約処理を手動で行います。その後記録された内容を見ると、どの画面でどのボタンを押したか(XPath)の履歴が残っているので、これを利用して selenium で操作をシミュレートします。従ってKatalon Recorder は予約処理プログラムの動作には必要ではありません。

構成

メールを利用したウェブサイト予約の流れ

予約対象の音楽練習室ウェブサイトの構成(画面遷移)

  • ログイン画面
  • 予約したい音楽練習室の選択画面
  • 各練習室の予約状況の表示画面
  • 予約画面

典型的な画面遷移だと思います。 ただ、ウェブサイトによって各画面の構成は異なり、本記事を利用してどこかのウェブサイトに適用する際には参考にならないと思うので、 詳細な説明は割愛します。

機能

サブジェクトに「check」とだけ入れて自分宛てにメールを送信すると、AからGまで7つある音楽練習室の空き状況をまとめてHTMLメールで返信してくれます。ウェブ画面では各練習室毎にページが違うので、例えば「18時から空いている部屋」が知りたいときに行ったり来たりする必要がありますが、その手間が減ります。

サブジェクトに「kakunin」とだけ入れて自分宛てに送信すると、自分(娘)の予約状況がメールで自分に送信されます。

サブジェクトに「yoyaku A 19」とだけ入れて自分宛てに送信すると、ルームAを19時から予約します。予約結果が自分に送信されます。 タッチの差で塞がっていたりしたら、予約失敗したと送信します。

サブジェクトに「cancel」とだけ入れて自分宛てに送信すると、自分の予約が取り消されます(このスタジオでは、1ユーザが上限1つしか予約できないので、どの予約をキャンセルするかの選択はない)

コードの説明

コードは下記gist repository にあります。

web_reservation_by_email.py https://gist.github.com/ZudenSachenselbst/74562f404a6e043032ad501a90fc32ea

以下上記コードの各部分を説明していきます。

固有値の定義

予約対象の音楽練習室のウェブサイトのURL、ログイン用IDとパスワード、 予約に使うメールサービスのsmtp メールサーバー、メールアドレス、パスワードといった固有値を設定します。

selenium の起動

pythonselenium 関連のライブラリのロードです。 そのあと selenium を headless(画面なし)で起動します。 デバッグする際には画面ありにすると便利です。 windows OS と linux のどちらでも使えるよう小細工がしてあります。 seleniumのバイナリ( chromedriver.exe あるいは google-chrome-stable)があるフォルダは適宜変更してください。

部屋の空き状況(7部屋)の確認

ウェブサイトにログイン後、各部屋の空き状況画面を表示させて、その画面を png 画像でダウンロードします。 その後「戻る」ボタンを押して、サイトからログアウトします。

メールへの画像の添付

取得したpng 画像をMIME パートとしてメールに添付します。

部屋の空き状況をメールで送信する

上記処理で取得した各部屋の空き状況(png画像)をHTMLメールに添付します。 SMTPメールサーバーにSSL 接続してログイン(認証)後、メールを娘に送信します。

娘の予約情報の確認(画像取得)

selenium を使ってウェブサイトに娘のアカントでログインし、娘の予約情報を確認します。予約状況のウェブ画面を画像ファイルとしてローカルファイルに保存します。

予約状況をメールで送信

上記処理で取得した娘の予約情報(画像)を、娘のメールアドレス宛に送信します。

予約処理

selenium を使ってウェブサイトに娘のアカントでログインし、メールで指定された部屋、時間で予約を行います。 コード的には「予約状況の確認」と大して変わらないので説明は割愛します。

メールの監視

娘が自分宛てに送信するメールを1分毎にチェックします。 サブジェクトを確認して、

  • 空き部屋状況を取得して娘に送る
  • 指定された時間・部屋で予約をする。
  • 自分の予約を確認する
  • 自分の予約をキャンセルする

のどれかを実施します。

苦労した点

iphone のメールアプリの仕様 がウェブで見つけられずに苦労しました。 娘にスマホで添付画像がどう見えたか確認しながら、送信したメールのMIME構成と比較しつつ仕様を見つけていきました。 iphone のメールアプリは添付画像をデフォルトで表示してくれるので、当初は普通のtextメール+添付画像で送信していたのですが、添付画像が複数あるとうまく表示されません。仕方なくHTML メールにしました。

python で画像を含むHTML メールを作成 するのに苦労しました。 MIME マルチパートを python でいじる方法の勉強になりました。

Katalon Recorderが生成したコード中のHTML要素指定の修正

Katalon Recorder が出力したコードの中のブラウザ要素指定(Xpath)が効かないときがあります。かつ人間には分かりにくい指定方法だったので、chrome developer tool を利用してもっとわかりやすい&確実な記述にしました。下記サイトが便利でした。

便利なXPathまとめ - ZOZO Technologies TECH BLOG https://techblog.zozo.com/entry/xpath

Seleniumで要素を選択する方法まとめ - Qiita https://qiita.com/VA_nakatsu/items/0095755dc48ad7e86e2f

[Selenium] Google Chrome を使って、簡単にXPATHセレクターを調べる | nobuhiroharada.com https://nobuhiroharada.com/2018/06/22/easy-to-know-xpath-selector/

独り言

昔はウェブページにアクセスして操作するプログラムをpython で書く場合 beautifulSoup 等のライブラリを使って書いていたのですが、

  • robot 排除のウェブサイトが増えた
  • https 接続処理が面倒
  • cookie の処理が面倒

という問題がありました。 selenium を使うことでこれらの問題を回避できます。

まとめ

なんとか1日で作り上げて娘が月曜に使うのに間に合いました。やれやれ。タイトルでは「スマホで」となっていますが、メール送信できればPCでもケータイでも利用可能です。 1分毎にメールサーバーにポーリングに行く所がイマイチですが、そのうち改善したいと思います(どうやるんだろう?) その後、予約したい部屋が塞がっているときの処理等を改良しましたが、基本放置しています。ウェブサイト毎にコードの selenium 部分は修正する必要がありますが、一度作ればしばらく持ちます。修正も容易です。 みなさんも、子供から「学校のウェブ連絡が見れないからブラウザアプリいつでも使えるようにしてー」と云われたときに是非ご利用下さい。😄

*1:React Native や Kotlin の勉強を想定していたのだが。。。

はてなブログにソースコードを行番号付きで範囲指定で張り込む(gist-embed.js)

はてなブログの標準的な挿入方法だと、下記のようにファイル全体が挿入されてしまう。 (長いので折りたたんでいます)

gist74562f404a6e043032ad501a90fc32ea

gist-embed.js を使うと、下記のように挿入したい範囲を指定することができる。 記事の中で以下のように書くと

<code data-gist-id="***gist.github.comのファイルへのハッシュ***" data-gist-line="1-8" data-gist-caption="web_reservation_by_email.py"></code>

下記のように表示される。

設定方法

下記参照

[Gist] gist-embedの使い方を調べてみた (1) 〜 id, file, caption, hide-footer 〜 - NP メモリア https://nprog256.net/post/2019/02/how-to-use-gist-embed-v1/

はてなブログ】 gistをファイルごとに分けて貼る - drag n drop https://yellowarrow.hatenablog.com/entry/2015/04/19/200000

昔はjquery を実装に使っていたので jquery も入れる必要があったが、最近は不要になったとのこと。嬉しい。 行範囲指定以外にファイル別に貼ることもできる。

設定画面で

<script
 type="text/javascript"
 src="https://cdn.jsdelivr.net/npm/gist-embed@1.0.4/dist/gist-embed.min.js"
></script>

をプロダクトタイトル下に張り込む。

embed.js の設定方法

その他

標準的な挿入方法の説明は下記参照

はてなブログソースコードを貼る方法(Gistを利用) | まろりかの自由帳 https://www.marorika.com/entry/code-on-hatenablog-with-gist

下記のように昔は ?slice=【表示開始行番号】:【表示終了行番号】_ を script タグ内部のURLの末尾に付加する方法もあったようだが、今では使えない1

はてなブログGitHubのコードを貼り付け/引用する - メンチカツには醤油でしょ!! https://ryoichi0102.hatenablog.com/entry/2015/11/13/091803


  1. gist URL が<script src=“http://gist-it.appspot.com/・・・となっている時点でアウトですね。

ブラームス バイオリン・ソナタ1番「雨の歌」 in G major, Op. 78, "Regensonate"

来週のカントロフ&上田晴子のブラームスバイオリンソナタ1番(雨の歌)に備えて、久しぶりに同曲を youtube の3つの演奏で聴いた。

(1) オイストラフ&無名ピアニスト

1,3 楽章は早めのテンポで進む。はあまりルバートしない。 テンポが早いせいで曲の構成がよく分かり、ソナタ形式の説得力がある。 この曲を早めのテンポで弾くのは実はアリで、なぜなら早めのテンポだと、ふっとしたさりげない陰影を表現するのに意外と良いから。 ポルタメントの仕方が古いが、さすが巨匠、意志的な構成力の強い演奏だった。

(2) シェリングルービンシュタイン

おそめのテンポでオーソドックスにじっくり聞かせる演奏。ピアノが美しい。 さすが両巨匠、バイオリンもピアノもどちらも意図がはっきりしているのに、ピアノトリオのようなぶつかり合いでななく調和が生まれる。不思議だ。

(3) パールマンアシュケナージ

あまり期待していないので、3楽章だけ。 早めのテンポでよく歌う、レベルの高い演奏だ。しかしこの曲には合わない。 諦念の音楽をそんなに朗々と歌ってもねえ。。 アシュケナージのピアノはやはり、よく分からかなかった。

雨の歌を聴いているといろいろなことが脳裏に浮かぶ

バイオリンの最初のスラースタッカートをどう弾くのかがまずは重要なのだが、これは正解はない。あるいはコーダの同じ音型に達したときに納得感があればどれでもOK

ブラームスの音楽はともすると浅田彰が云うように音楽的構成に「逃げる」ときがあるのだがこの曲の場合、モチーフ自体が最初から「逃げている」というか、しとしと降る雨?を慈しむようなささやかな感興が主題なので、それは問題にならない。この曲の3楽章のコーダ、諦念の果てに奇跡的な美と感興が訪れる。晩年のピアノ曲に似ている。

しかし不思議なのは、この曲の演奏機会の存在だ。 曲自体は素晴らしいが、人が明日を生きるために必要とするような音楽ではない。 巨匠のマスターピースというだけで演奏機会は多いだろうが、この曲の演奏が真の意味で当為となる状況が思い当たらない。 唯一思い当たるのが、年をとった演奏家が自分の人生のコーダとしてこの曲を演奏するケースだ。 今回のカントロフの演奏は、まさにそういう演奏である。

また、ブラームスは晩年この曲(雨の歌)をチェロ用に編曲しようとしていたと聞く。 何をしたかったのだろうか?

graphviz 埋め込みテスト

参考URL

 dot をコンパイルするオンラインサービス