素のJavaScriptでAJAX処理を書くには?
対象のコードはこちら
こちらからお借りしました。
var r = new XMLHttpRequest(); r.open("POST", "path/to/api", true); r.onreadystatechange = function () { if (r.readyState != 4 || r.status != 200) return; alert("Success: " + r.responseText); }; r.send("banana=yellow");
上から読んでいきます
まず XMLHttpRequest オブジェクトから。
使い方ですが…
まずコンストラクタ XMLHttpRequest() を実行して、初期化する必要があります。
var r = new XMLHttpRequest();
r.open() はリクエストの初期化を行います。
developer.mozilla.org
var r = new XMLHttpRequest(); r.open("POST", "path/to/api", true);
引数は前から順にメソッド、URL、非同期/同期 (true/false) です。
同期通信は多くのブラウザで非推奨とされているとのこと。
var r = new XMLHttpRequest(); r.open("POST", "path/to/api", true); r.onreadystatechange = function () { if (r.readyState != 4 || r.status != 200) return; alert("Success: " + r.responseText); };
r.onreadystatechange は、readystatechange イベント ( XMLHttpRequest の readyState 属性が変化)が発火するたびに呼ばれる EventHandler です。
構文はこんな感じ。
XMLHttpRequest.onreadystatechange = callback;
イベントが発火すると、callback に指定した関数が実行されます。
ではこの readyState 属性が何者かというと…
developer.mozilla.org
値 | 状態 | 説明 |
---|---|---|
0 | UNSENT | クライアントは作成済み。open() はまだ呼ばれていない。 |
1 | OPENED | open() が呼び出し済み。 |
2 | HEADERS_RECEIVED | send() が呼び出し済みで、ヘッダーとステータスが利用可能。 |
3 | LOADING | ダウンロード中。responseText には部分データが入っている。 |
4 | DONE | 操作が完了した。 |
var r = new XMLHttpRequest(); r.open("POST", "path/to/api", true); r.onreadystatechange = function () { if (r.readyState != 4 || r.status != 200) return; alert("Success: " + r.responseText); };
4の状態は成否に関わらず処理が終わってます。
status 属性はHTTPステータスコードです。
つまり、処理が正常に終了したときだけ、レスポンスを alert 関数で出力するようになっています。
callback 関数の定義が終わったら、あとは r.send() でデータを送信します。
送ったあとは、サーバー側での処理を経て、callback 関数に落ち着くというわけですね。
var r = new XMLHttpRequest(); r.open("POST", "path/to/api", true); r.onreadystatechange = function () { if (r.readyState != 4 || r.status != 200) return; alert("Success: " + r.responseText); }; r.send("banana=yellow");
さいごに
JavaScript はいろんなフレームワークやライブラリが出ておりますが、素の仕組みを知っておくことも大事ですよね。
と思ったのが今回のきっかけでした。
mozilla のサイトにマニュアルがあるので、調べるのに便利ですね。
また似たような記事を書くかも知れません。
以上でした!
Python3でWebサイトのスクレイピングをCygwinから
はじめに
特定のWebサイトの情報抜き出しを、Python3でやってみました。
Googleのクローラーのようなことをやるのは大変です。
でも、特定のサイトの特定の情報なら、そんなに難しくはないので、ぜひ挑戦してみることをオススメします。
ただし、相手のサイトに迷惑をかけるようなことだけはNGです。
過去捕まった人が出た事例もありますので、ご注意を…。
準備から
まずはPython本体
まずPython3を入れるところから…
※Cygwin使ってます。
$ apt-cyg searchall python3 $ apt-cyg install python3
searchallで探すとすぐ見つかりますので、インストールは簡単です。
ただし、"python3"というファイル名になっているので、シムリンクを作成して、"python"で実行できるようにしておきます。
これはお好みでどうぞ。
$ which python3 /usr/bin/python3 $ ln -s /usr/bin/python3 /usr/bin/python $ python --version Python 3.6.3
パッケージ管理システムのインストール
pip というPythonのパッケージ管理システムを入れます。
$ apt-cyg searchall pip $ apt-cyg install python3-pip
注意点として、今回入れるのはPython3用のpipであること。
"python3-pip"を指定しましょう。
install後は"pip3"になることも要注意。
$ which pip3 /usr/bin/pip3 $ ln -s /usr/bin/pip3 /usr/bin/pip $ pip --version pip 9.0.1 from /usr/lib/python3.6/site-packages (python 3.6)
こちらもおまけですが、シムリンクを作成してみました。
スクレイピングに便利なパッケージを入れる
Beautiful Soupを使います。
Beautiful Soup Documentation — Beautiful Soup 4.4.0 documentation
「XMLやHTMLからデータを取得するためのPythonライブラリ(意訳)」とのこと。
そしてBeautiful Soup 4が最新のようです。
私は普段PHPを使いますが、PHPでは取得したHTMLからの抽出が大変なので、この手のライブラリが充実しているPythonはいいですね。
$ pip search beautifulsoup4 $ pip install beautifulsoup4 Collecting beautifulsoup4 Downloading https://files.pythonhosted.org/packages/9e/d4/10f46e5cfac773e22707237bfcd51bbffeaf0a576b0a847ec7ab15bd7ace/beautifulsoup4-4.6.0-py3-none-any.whl (86kB) 100% |????????????????????????????????| 92kB 1.0MB/s Installing collected packages: beautifulsoup4 Successfully installed beautifulsoup4-4.6.0 You are using pip version 9.0.1, however version 10.0.1 is available. You should consider upgrading via the 'pip install --upgrade pip' command.
何やらpipのバージョンが古いと言われてますので、言われたとおり
pip install --upgrade pip
を実行しておくことをオススメします。
ようやくコーディング
特定のサイトを指定するわけにもいかないので、サンプルを提示しようと思います。
# coding: UTF-8 # Webサイトへのアクセスに使うライブラリをimport import urllib.request from bs4 import BeautifulSoup url = "対象のURL" try: # URLにアクセス html = urllib.request.urlopen(url) except: print('Cannot open the url.') try: # HTMLのパース soup = BeautifulSoup(html, "html.parser") except: print('Cannnot read the html data.') # HTMLを解析、欲しいデータを持ってくる targets = soup.select('#contents ul li a') # タグの中の文字列を取得する for target in targets: text = target.get_text() print(text)
HTMLの中から特定のタグを探す手段はたくさんあります。
今回は比較的わかりやすいと思われるCSSセレクタを使いました。
タグの中の文字列を取得する手段も、複数用意されています。
詳細はマニュアルを参照のこと。
Beautiful Soup Documentation — Beautiful Soup 4.4.0 documentation
最後に
今回はサイトから特定のデータを取得することが目的だったので、あまりBeautiful Soup自体の深掘りはしませんでした。
対象によっては異なるメソッドを使うほうが効率がよかったりするでしょうから、ぜひマニュアルをご一読くださいませ。
以上でした。
GAS(JavaScript)でよく使う日付フォーマット処理を書きました
はじめに
最近、GAS(Google Apps Script)を使っているのですが、ほぼJavaScriptでして、日付の扱いがちょっと面倒です。
そこで今回、日付をいろんな形式で出力できるフォーマッターを作成しましたので、共有します。
ソースコード
/** * 日付のフォーマッター * @param {date} date dateオブジェクト * @param {string} format 書式フォーマット */ function formatDate(date, format) { format = format.replace(/yyyy/g, date.getFullYear()); format = format.replace(/mm/g, ('0' + (date.getMonth() + 1)).slice(-2)); format = format.replace(/dd/g, ('0' + date.getDate()).slice(-2)); format = format.replace(/aaa/g, ['日','月','火','水','木','金','土'][date.getDay()]) format = format.replace(/AAA/g, ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'][date.getDay()]) format = format.replace(/HH/g, ('0' + date.getHours()).slice(-2)); format = format.replace(/MM/g, ('0' + date.getMinutes()).slice(-2)); format = format.replace(/ss/g, ('0' + date.getSeconds()).slice(-2)); format = format.replace(/SSS/g, ('00' + date.getMilliseconds()).slice(-3)); return format; };
これをテスト実行してみます。
/** * テスト実行 */ function sample() { var dateObj = new Date(); Logger.log(formatDate(dateObj, 'yyyy/mm/dd(AAA) HH:MM:ss.SSS')); }
このsampleを実行すると、こんな出力になります。
スクリプトエディタの「表示」→「ログ」、またはCtrl + Enterでも表示できます。
[18-06-10 08:33:00:835 JST] 2018/06/10(Sun) 08:33:00.833
解説
メインの方
date.getMonth()
は 0 - 11 の数字が返るので、+1しなくてはなりません。
date.getDay()
は曜日を取得しますが、こちらは0 - 6 (日、月、…土)で返るので、こちらも変換しなくてはなりません。
['日','月','火','水','木','金','土']という配列を作って、要素部分に date.getDay() を当てはめれば、曜日が取得できます。
もう少し丁寧に書くならこんな感じです。
var dayOfWeekList = ['日','月','火','水','木','金','土']; var dayOfWeek = dayOfWeekList[date.getDay()];
テスト実行の方
new Date();
は引数なしなので、今現在の日時になります。
Logger.log();
を実行することで、スクリプトエディタの「表示」→「ログ」にログが残ります。
Ctrl + Enterでも表示できます。
formatDate(dateObj, 'yyyy/mm/dd(AAA) HH:MM:ss.SSS')
formatDate関数は、ただ文字列を置換しているだけなので、取得したい情報を文字列で指定するだけです。
日本語風に取得したければ、こんな感じでしょうか。
formatDate(dateObj, 'yyyy年mm月dd日(aaa)')
VirtualBox + CentOS 7にTeratermを使ってsshでログインする
はじめに
VirtualBox上に構築したCentOSが前提ですが、そのままでは操作がしづらいです。
ここはぜひターミナルエミュレータからアクセスしましょう。
今回はTeratermを使用します。
CentOS側で設定
「Oracle VM VirtualBoxマネージャー」
ではなく、
「CentOS [実行中] - Oracle VM VirtualBox」
の方のウィンドウにて設定します。
メニューの中に「デバイス」があるので、そこから「ネットワーク」→「ネットワーク設定…」を選択。
最初は見えないですが、「▼高度」と書かれたところをクリックすると、「ポートフォワーディング」が出てきます。
それをクリック。
このポートフォワーディングのルールを追加します。
ルールの名前は何でもいいです。
ホスト側のポート番号も空いていれば何でもOKです。
ゲストポートは、sshでの接続を行うので、22番にしましょう。
その後、CentOSを再起動しましょう。
(必要だったはず…)
では、Teratermで接続を試みます。
設定は画像の通り、localhostのポート番号は2222です。
ポートフォワーディング(ポート転送)の設定のおかげで、2222番ポートへのパケットは、22番ポートへ転送される、というわけです。
設定がうまくいっていれば、初めて接続するホストですよ的な警告が出ると思われます。
その後、上記画像のようなユーザー名とパスワードを求められる画面が表示されます。
Virtual BoxにCentOS 7を入れる
はじめに
自宅用PCにて、久しぶりに仮想環境を構築してみました。
特に困ることはありませんでしたが、記録として残しておきます。
バージョンは下記のとおりです。
・Windows 10
・CentOS 7 (Minimal)
・VirtualBox 5.2.8
手順
Oracle VM VirtualBox をインストール
Oracle VM VirtualBox
正式名称はこうらしいです。
Downloads – Oracle VM VirtualBox
OSによって異なるインストーラーがあるので、今回はWindows版をダウンロードします。
インストール中に、下記3つもインストールするように言われるので、大人しく入れます。
あとは案内に従えば、問題なくインストールできると思います。
CentOSのイメージファイルを取得
Download CentOS
・DVD ISO
・Everything ISO
・Minimal ISO
と3つありましたが…私はMinimalを選択。
DVDは用途が違いますし、Everythingは8GBもあったのでやめました。
Minimalは800MBくらいでした。
VirttualBox上に新規で仮想マシンを乗せる
画面左上の「新規」というボタンから始めます。
CentOSはRed Hat系なので、LinuxのRed Hatを選択。
今回私は64bit版を使用するので、64bitを選択。
メモリはデフォルト値を使用しました。
仮想HDDは追加することにし…
VirtualBox以外で使うつもりはないので、VDI形式にしました。
ストレージは固定、サイズも規定値で。
そうすると、VirtualBoxの画面に、Red Hatアイコンが追加されます。
これを起動します。
起動ハードディスクを指定するように言われます。
ここでようやくダウンロードしたISOファイルを使うことになります。
CentOSの設定とインストール
ここからはCentOS側の設定になります。
キャプチャを撮り忘れましたが、黒い画面が開いたら、「Install CentOS 7」を選択します。
言語設定は日本語に。
「ネットワークとホスト名」にあるイーサネットは、画面右上のボタンを「オン」にしておきましょう。
「インストール先」は、作成した8GBのHDDにチェックを付けてあげます。
HDDを指定してあげると、画面右下の「インストールの開始」が押せるようになると思います。
あ、キーボード設定は、US配列をお使いの方は、そのように設定しましょう。
私はUS配列なのに日本語設定をしてしまったせいで、あとで変更することになりましたので…。
インストール中に、rootのパスワード設定とユーザーの追加ができます。
インストールには少々時間がかかるので、その間に両方とも設定しておくと良いでしょう。
当然、あとでもできます。
インストールが終わると再起動を求められるので、「再起動」ボタンをぽちり。
そうするとログインユーザー名を求められる画面が表示されますので、これにて完了です!
おまけ: 何かを始める前に
VirtualBoxのターミナル画面から抜けるには
右Ctrlキーが割り当てられています。
マウスやキーボード入力をターミナル画面から抜けたい場合には、押してみましょう。
sudo権限を付与
sudoできると何かと便利です。
# visudo
rootの下に追記しましょう。
詳細な説明は省きます。
root ALL=(ALL) ALL userName ALL=(ALL) ALL