新着記事

Viewing posts from August, 2022

Web ページの動作検証のためのボットスクリプトを Windows 上で作る

この文書は、開発経験の無いチームがウェブアプリケーションの動作検証の責任を持つケースで、検証を簡単なプログラムで行うアプローチについての手法を解説しています。

Webアプリケーションの動作検証の際、手動で実行する以外にプログラムで検証すると便利です。開発者であればは検証コードを書くのは簡単ですが、開発経験の無い方はどこから始めたらいいかわからないと思いますので、比較的用意にスクリプトに入門できるように紹介します。OS は Windows を対象としています。

本記事で紹介しているようなプログラムによるリクエストは悪意の有無にかかわらず、不正アクセス禁止法での不正アクセスとみなされたり、電子計算機損壊等業務妨害罪等に問われる可能性があります。実際にリクエストを行う場合は、自社の管理する、許可されたサーバに対してのみ行うようにしてください。

HTTP の リクエスト・レスポンスの仕組みを知る

まずは、ウェブサーバと通信している HTTP のリクエストがどのようなものか知ることが必要です。この知識があいまいなままだとボットのスクリプトは書けません。

まずは、ウェブブラウザに搭載されている開発者ツールを使ってリクエストやレスポンスを観察するのが、良い勉強になります。

ウェブサーバに対して、

  • どの URL に対して
  • どのHTTP メソッドで (GET, POST, HEAD, PUT 等)
  • どのような HTTP ヘッダーで
    • cookie
    • referer
    • user-agent
  • どのようなリクエスト本文(body)で

以上を意識して、ブラウザの行っているリクエストをスクリプトで再現できれば、どのようなクライアントを使おうが、ウェブサーバからはブラウザでのリクエストと同じようにレスポンスが返ってきます。

Chrome のデベロッパーツールの使い方

  1. Google Chrome を起動してください。
  2. Shift + Ctrl + I を押してください。
    右側にデベロッパーツールが表示されます。
  3. デベローパーツールの上部のタブで、Network を選択してください。
  4. ブラウザの URL 欄に適当にページを打ち込み、ページを表示されてください。
  5. リクエスト一覧が表示されますので、適当なリクエストをクリックして選択してください。
  6. Headers にリクエストヘッダ、レスポンスヘッダ
    Payload にリクエスト本文
    Response にレスポンス本文
    が確認できます。
    特に、Headers のリクエストヘッダでどのようなヘッダを送っているか、確認してください。

Headers の中でも、cookie は特に注目してください。cookie の扱いはボット作成の中で最上位に重要な項目です。不安があれば、他のサイトや書籍を参考に学習してください。

また、 cookie の内容は認証情報を含むため、サイトのログインパスワードと同じぐらい重要な秘密情報です。安易にコピーは行わず、また絶対に他者に教えないようにしてください。ブラウザの cookie を格納している場所は安全ですが、他の場所にコピペすると漏洩リスクとなり、ログイン権限を奪われる危険性があります。

HTTPヘッダとクッキーの学習ができるサイト

HTTP ヘッダ、クッキーについての概要は、とほほ先生のサイト、わわわ先生のサイト、あと Wikipedia を読めば理解できます。

HTTPヘッダ

Cookie

ブラウザを手動で操作する以外での HTTP リクエストを行う方法

HTTP リクエストは、結局は特定の文字をサーバに送るだけですので、様々なクライアントで行うことができますが、よく使われるものを紹介します。

Postman

https://www.postman.com/
フリーの Windows クライアントがあります。GUI でリクエストを構築することができますし、スクリプトによる制御処理も書けます。有用なツールですが、最初は機能が多く複雑なため戸惑うかもしれません。

長所
  • GUI で完結する
  • 大量のテストリクエストの管理がしやすい
  • 署名の計算等、複雑な計算を伴う処理も行える。
短所
  • 複雑なため習得が難しい
  • 単純なリクエストを出すだけであれば冗長

curl

mac や linux を使う方には定番のコマンドラインツールです。Windows 10 からは標準でインストールされています。

長所
  • インストール済みなのですぐに使える
  • 単純なリクエストを1発出すだけなら一番適している
短所
  • 計算を伴う順次リクエストには向かない

Selenium や Puppeteer

プログラムで Chrome などのブラウザを実際に起動し、自動操作するための Selenium や Puppeteer といったツールがあります。

ブラウザを起動するため、ページ内で JavaScript を豊富に扱うページも自動操作し、検証することができます。

最近のウェブサイトは、React や Vue といった JavaScript を用いて表現するサイトが多くなってきており、その場合は Postman, curl, 後述するシンプルなスクリプトでは十分な検証ができない場合がありますので、 ページ内の JavaScript の動作検証が必要になる場合実際のブラウザを実行させる以外に無く、自動操作するには Selenium や Puppeteer を使うしかありません。

扱うには高度なプログラミング知識が必要ですので、今回は言及しません。

長所
  • ブラウザでの JavaScript の実行が必要であればこれ一択
  • 表示レイアウトの確認にも使える
短所
  • 実行環境の構築が難しくて、手間がかかる。
  • 他の、単純なリクエストを出す方式に比べると遅い。
  • 様々な要因により安定させて動作させるのは難しい。業務レベルで使うには高い技術が必要。

Rest Client ( .http)

ドットエイチティーティーピーファイルを作り、その記述したリクエストを簡易に何度も再現させることができます。VSCode や JetBrains エディタの機能として扱うことができ、記述が簡単で読みやすいため私は(当社内でも)かなり使います。

長所
  • 習得が容易
  • スクリプトの構文が容易で書きやすく読みやすい
  • スクリプトのチーム内共有が容易
  • レスポンスへの簡易的なテストを行うことができる
短所
  • 計算を伴う複雑な逐次処理はできない

プログラミング言語でスクリプトを組む

Python, PHP, Javascript, Ruby などで、既にある便利な HTTP クライアントライブラリを使ってスクリプトを組む方法です。
今回の記事ではこちらを今回紹介します。

長所
  • 条件分岐を含む複雑な制御処理が得意
  • 複数セッションによる並列リクエストを再現したい場合は一択
  • 完全無人での自動実行が容易
  • 書いたコードの再利用が容易
  • 処理結果の外部ツールへの連携が柔軟に行える
短所
  • 環境構築が手間
  • 単発のリクエストを検証したい場合は RestClient や Curl, Postman と比べても冗長

Windows に Python 実行環境をインストールする

Microsoft Store からの Python のインストール

Microsoft Store で Python パッケージが提供されるようになり、昔と比べて環境構築が楽になりました。

Microsoft が提供している、初心者向けの Python の開発ガイドが良くできています。この流れにそって進めれば問題なく進められますので、こちらも参考にしてください。

Microsoft Store のアプリを開き、 Python を検索して Python 3.10 をインストールします。

インストール後、念の為再起動を行い、その後コマンドプロンプトを起動して python と打ち込んで、 python が起動するか確かめてください。

Python 公式サイトからの Python のインストール

コマンドプロンプトで、 python と打ち込んで python が起動しないようであれば、Microsoft Store からインストールした Python はアンインストールし、 Python の公式サイトから Windows 版のインストーラパッケージをダウンロードしてインストールしてください。

その際、PATH を追加編集するかのオプションが表示されるので、チェックを入れてください。

https://www.python.org/downloads/

requests ライブラリのインストール

Python の インストールが完了したら、ウェブを操作するボットの作成に必須ともいえる、 requests ライブラリをインストールします。

コマンドプロンプトや PowerShell で、

python -m pip install requests

と入力すると、インストールが完了します。

Visual Studio Code のインストール

エディタは Visual Studio Code を使います。

Microsoft Store から Visual Studio Code を検索してインストールしてください。

プロジェクトフォルダの準備

Windows の、ドキュメントフォルダの下にtest-bot フォルダを作ってください。

VSCode を起動し、 File -> Open Folder で test-bot フォルダを開いてください。

フォルダを開いたら、左側のペインで右クリックし、 New File から first_bot.py というファイルを作ってください。

作成後、右下に「インタープリターを選択」と表示されているようであればクリックしてください。Microsoft Store からインストールした Python が、おすすめに表示されているので選択します。

右下に CRLF と表示されている箇所は、改行コードの設定が表示されています。CRLF は一般的ではないため、クリックして LF に変更しておきます。

Python の機能拡張のインストールがおすすめされると思いますので、Python, Pylance の機能拡張をインストールします。

スクリプトを書く

レスポンス本文を表示するだけのスクリプト

import requests
response = requests.get('https://www.torico-corp.com/')
print(response.text)

これは、 https://www.torico-corp.com/ のレスポンス本文を表示するだけの単純なプログラムです。
書いたら、右上の ▶ ボタンを押して、実行させてください。
出力結果がずらっと表示されます。

requests ライブラリについてのドキュメント

レスポンスの経過時間とステータスコードを表示するスクリプト

import requests
response = requests.get('https://www.torico-corp.com/')
print('経過時間 {}ms'.format(response.elapsed.microseconds / 1000))
print('ステータスコード {}'.format(response.status_code))

このスクリプトは、レスポンスの応答時間とステータスコードをコンソールに表示します。

Python に慣れてきたら、結果をファイルに記録するように改修することで、簡易的な負荷監視などに応用できます。

サイトの検索結果ページからを解析するスクリプト

Webサイトの検索ページにリクエストを行い、結果の HTML をパースしてコンソールに表示するスクリプトです。

HTMLをプログラムで扱えるように解析するために、 BeautifuSoup というライブラリをインストールします。

BeautifulSoup のインストール方法

コマンドプロンプトで

python -m pip install beautifulsoup4

でインストールできます。

BeautifulSoup の解説記事

コード

import requests
from bs4 import BeautifulSoup
response = requests.get('https://tech.torico-corp.com/search/?q=docker')
soup = BeautifulSoup(response.content, features='html.parser')

for h2 in soup.find_all('h2'):
a = h2.find('a')
if not a:
continue
print(a.text)
print(a['href'])

上記スクリプトは、TORICO の技術開発ブログを「docker」で検索し、出てきた記事のタイトルとリンクURL を表示しています。

メールアドレスとパスワードでウェブサイトにログインする

最後に、メールアドレスとパスワードでログインをするスクリプトの雛形を記載します。

requests ライブラリは、クッキー管理を行うことのできる Session というしくみがありますので、それを使います。

解説記事

検証するサイトによりますが、多くの場合は、ログイン時に「CSRFトークンの検証」と「Refererヘッダの検証
User-Agent が悪質なボットでないかの検証」を行っていると思いますので、そこを考慮してスクリプトを作れば、ログインが行えるはずです。

下記のような自動ログインのスクリプトは、必ずご自身が権限を持つサーバにのみ行うようにしてください。他者のサーバに行うと罪に問われる可能性があります。

URL 等は架空のものです。

import requests
from bs4 import BeautifulSoup

# session を作る
s = requests.session()
# User-Agent を設定する場合
s.headers['User-Agent'] = 'Tester Python Bot'

# ログインフォームを取得する
response = s.get('https://example.com/login-form/')

# HTTP のステータスコードに異常が無いか確認
response.raise_for_status()

# ログインフォームをパースする
soup = BeautifulSoup(response.content, features='html.parser')

# パースしたログインフォームから CSRF トークンを取得する
csrf_token = soup.find('input', {'name': 'csrftoken'})['value']

# ユーザー名とパスワードをいれてログインフォームを送信する。
response = s.post(
'https://example.com/login-form/',
data={
'email': 'tester@example.com',
'password': 'MY_AWESOME_PASSWORD',
# 先程取得した CSRF トークンを付与
'csrftoken': csrf_token
},
headers={
# Referer を付与
'Referer': 'https://example.com/login-form/',
})

# HTTP のステータスコードに異常が無いか確認
response.raise_for_status()

# ログイン後の URL が正しいものであるか確認
assert response.url == 'https://example.com/mypage/'

# この時点で、セッション s はログイン済みの状態なので、
# マイページ等をリクエストすることが可能
response = s.get('https://example.com/mypage/myprofile/')

そうだ、mysql8.0サーバーを構築してみよう

ども、お久しぶりです。

オンプレのインフラ構築を担当することが多い四斗邊です。

今回は社内の要望でmysql8.0サーバーを社内ネットワーク上に構築する!というのが目標です。

結構ありふれたネタだと思いますが、社内に向けた手順書のような形で残しておきたかったので今回記事しました。

PC構成


  • CPU intel i5-12400 6コア12スレッド 2.5GHz

  • メモリー CT2K32G4SFD832A メモリー32GB 1枚(レイテンシーは特に考えていない)

  • ベアボーンキット DeskMini B660

  • SSD WDS100T3X0E 1TB

これで10万円を切った構成になっています。
安くてそれなりに社内サーバーとしてはそこそこパワーがある構成にしてみました。
一番の特徴はなによりもベアボーンキットなのでコンパクトなのがいい。
個人的にはCPUはAMD派ですが、2022年8月上旬ではintelが安くてちょうどいいかんじでした。
家庭用なので消耗とか気になりますが、4年ぐらいは耐えてくれてると信じたい。

OSソフトウェア構成


OS ubuntu 22.04
DB mysql8.0.30

ubuntu以外も候補はありますが、構築経験があるのでこちらかなと。

mysqlインストール手順


*注意事項
手順の前にsshとかOS周りの設定は一通りしております。今回の手順はmysqlインストールに特化したものとご了承ください。

mysql-serverのインストール

$sudo apt install mysql-server

mysqlにログインする。

$sudo mysql
#ユーザー確認
mysql >select user,host from mysql.user;

インストールしているときに、すでにrootユーザーは作られているので、以下のコマンドでパスワードを改変する。hogeの部分は任意なパスワードに変える。

mysql > USE mysql; 
mysql >ALTER USER 'root'@'localhost' identified BY 'hoge';
一応権限の確認は以下で確認できる
mysql > show grants for 'root'@'localhost';

後々構築した後に気づいた点で、localhostになっているので、リモート時にはrootユーザーに入れないことがあった。

やっぱりここはrootユーザーのhost=%を作るに限る。(セキュアな面ではもうちょっとhost部分は制限したほうがいいかも)

mysql > CREATE USER 'root'@'%' IDENTIFIED BY 'hoge';
mysql > GRANT ALL ON *.* TO 'root'@'%';

これでリモート上でもrootで入れる。

文字のエンコードはutf-8に設定したかったので、my.cnfを以下のようにいじる。参考にしたURL↓

https://qiita.com/is0me/items/12629e3602ebb27c26a4

まずはmy.cnfの場所の特定。どうやら/etc/my.cnfが先で、次に/etc/mysql/my.cnfの順番で読み込まれるようだ。

mysql --help | grep my.cnf 
#以下結果 
order of preference,my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf

/etc/mysql/my.cnfの中身を見ると以下のような記載がありました。

!includedir /etc/mysql/conf.d/ 
!includedir /etc/mysql/mysql.conf.d/

/etc/mysql/conf.d/のディレクトリに入れると反映されるのでは?ということで、ここにmy.cnfを設置してみる。

保存するその前に、一旦、サーバー上でmysqlが止まっているか確認する。

mysqlが止まっているか以下でわかる。(すでに稼働している場合は周りに影響しないか注意してください。)

$sudo service mysql stop
#以下の内容を入れて/etc/mysql/conf.d/my.cnfに保存する。 
[mysqld]
character-set-server=utf8mb4
[mysql]
default-character-set=utf8mb4
[client]
default-character-set=utf8mb4
#更新したら以下でリスタートする。
service mysql restart

あとは、リモート上でも接続できるようにサーバー上でリッスンを設定する。今回は、mysqlのポート3306をリッスンさせる。

mysqlインストール時にすでにポートはリッスンしているので、bind-addressとmysqlx-bind-addressのアドレスを変更するようです。

/etc/mysql/mysql.conf.d/mysqld.cnf
#bind-address = 127.0.0.1
#mysqlx-bind-address = 127.0.0.1

更新したら以下でリスタートする。

service mysql restart

そうすると、自動的に全てのアドレスから全てのアドレス:3306でリッスンできる。

sudo ss -talpn 
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 151 *:3306 *:* users:(("mysqld",pid=3822,fd=23))
ただ、この設定は少し強引すぎる。

社内サーバー用とかで事前に外部からのアクセスを制限できているなど限定した場面で活用するのが望ましい。というか一応ufwも確認する。

sudo ufw allow 22 #ssh 
sudo ufw allow 3306 #mysql
sudo ufw enable
sudo ufw status numbered
To Action From -- ------ ----
[ 1] 22 ALLOW IN Anywhere
[ 2] 3306 ALLOW IN Anywhere
[ 3] 22 (v6) ALLOW IN Anywhere (v6)
[ 4] 3306 (v6) ALLOW IN Anywhere (v6)

これでmysqlとsshのみ通るようにポートは開けることが確認できた。

ここまでで一通りのmysqlサーバの完成となる。実際に自身のPC上で確認してみてください。

以下のコマンドで入れたら成功です。

(もちろんローカル上にもmysqlは入れてるよね?)

mysql -h XXXX.example.co.jp -u root -p
パスワードを入力:hoge

できましたかね?これであなたもmysqlサーバー構築者だ、おめでとう!

できない人は個別のトラブルシューティングに従って解決してください。

結構最低構成でできたはずなので、時間はかからないのかなと思っています。

みなさん試してみてください。

Search