no-image

初心者のためのFlaskアプリ開発③ Flaskのテンプレートビューを使って画面に実行結果を表示させる

追記(2018/08/15)

ソースコードの全体像を載せてなかったので、Githubのリポジトリを公開しておく。
拙いコードで恥ずかしいが、記録として残しておく。

https://github.com/alumi-mic/flasksample-hatebu

 

今回はflaskアプリケーションでテンプレートビューを使用してページを表示するところまで実践する。

前回の記事:初心者のためのFlaskアプリ開発② FlaskでHelloWorldアプリをつくる

本記事の構成

この記事の構成は以下の通り。

  1. 今回作成するアプリケーションのファイル構成
  2. app.pyの作成
  3. テンプレートビューの作成
  4. 実行!
  5. お詫び

今回作成するアプリケーションのファイル構成

今回作成するファイル構成は以下の通り。
前回作成したflaskAppディレクトリ下に作成していく。
この記事は初心者向けの記事ではあるが、ディレクトリとファイルの作成は最悪コマンドがわからなくてもGUIでできるので割愛。
ファイルの解説も簡単に付け加えておく。

  /flaskApp
  ├── flaskAppDir/ #今回のアプリを置くためのディレクトリ
  │   ├── __init__.py #pythonスクリプトがあるディレクトリを表す役割を持つ。空のファイルでOK
  │   ├── time.py #メインのアプリケーション
  │   ├── templates/ #HTMLファイルを入れるためのディレクトリ、必ずtemplatesという名前にすること
  │   │   ├── layout.html #共通部分のHTMLを記述
  │   │   ├── index.html #アプリケーションで呼び出すHTML

app.pyの作成

今回はシンプルなアプリに。
内容としては簡単。
先日作成したはてぶのスクレイピングプログラムで抽出した人気記事を表示するだけのもの。

コードはこちら。

  from flask import Flask, render_template
  import requests
  from bs4 import BeautifulSoup

  app = Flask(__name__)

  @app.route('/')
  def index():
      hatebu_array = []

      r = requests.get('http://b.hatena.ne.jp/')
      content = r.content
      soup = BeautifulSoup(content, 'html.parser')

      for div in soup.select("div.entrylist-contents-main"):
          title = div.h3
          url = div.a
          user = div.span
          user_num = user.getText().split(" ")

          if int(user_num[0]) >= 20:
              data_list = []
              data_list.append(title.getText())
              data_list.append(url.get('href'))
              data_list.append(user.getText())
              hatebu_array.append(data_list)
          else:
          	next

      return render_template('index.html',hatebu_array=hatebu_array)

  if __name__ == '__main__':
      app.debug = True
      app.run()

bs4を使ったスクレイピング機能に関してはこっちの記事で簡単に解説してあるので割愛。

Python初心者が、Beautiful Soupではてぶ人気記事をWEBスクレイピング
Beautiful Soup×Pythonで、初心者でも10分でできるRSSスクレイピングを解説

今回はflaskで動作している部分を解説。
まずはインポート。
requestsとbs4を読み込む。
こちらはインストールが必要なので、入っていなければpip installで入れておく。

  from flask import Flask, render_template
  import requests
  from bs4 import BeautifulSoup

次がとても重要。

  app = Flask(__name__)

  if __name__ == '__main__':
      app.debug = True
      app.run()

app = Flask(__name__)は、appという変数にFlaskクラスのインスタンスを代入する処理。
flaskの基礎になるWSGIに基づくWebアプリケーションには、実際のアプリケーションを実装する呼び出し可能オブジェクトが必要になる。
それがflaskクラスのインスタンスである。
このflaskのインスタンスを明示的につくるのがこのコードの役割。

次に、if __name__ == ‘__main__’: 以下のコードについて。
こちらは、機能としてはapp.pyを実行すればサーバーが立ち上がるようにするためのものである。
コマンドで呼び出された場合は実行されるが、importなどにより呼び出された場合は実行されない、という機能になっている。
詳細は割愛。

次はテンプレートビューにデータを送るコードについて。

  if int(user_num[0]) >= 20:
          data_list = []
          data_list.append(title.getText())
          data_list.append(url.get('href'))
          data_list.append(user.getText())
          hatebu_array.append(data_list)
      else:
        next

  return render_template('index.html',hatebu_array=hatebu_array)

ここで行っているのは、はてぶのお気に入り数20以上の投稿のタイトル・URL・お気に入り数の三つのデータを抜き出して、hatebu_arrayに挿入する作業である。
hatebu_arrayは、以下のような二次元配列になる。

  [
    [title,url,users],
    [title,url,users],
    [title,url,users],
    [title,url,users],
          ・
          ・
          ・
    [title,url,users]
  ]

最後に、rennder_tenmplateメソッドでテンプレートにデータを送っている。
rennder_tenmplateメソッドは、第一引数に送り先のテンプレートファイル、第二引数以降に送りたい変数を入れる。
次はテンプレートの作成について。

テンプレートビューの作成

templatesディレクトリ下にある、layout.htmlをまずは編集。
これが複数のテンプレートの共通部分になる。

  <!DOCTYPE html>
  <html lang="ja">
    <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>はてぷ人気記事まとめ</title>
      <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous">
    </head>
    <body>
      {% block content %}
      {% endblock %}
    </body>
  </html>

基本は普通のHTMLと同じだが、bodyの中に特殊な記述がある。
これがflaskが採用しているテンプレートエンジンjinja2で、PythonコードをHTML内に書き込むための記法である。

  <body>
    {% block content %}
    {% endblock %}
  </body>

次に、今回のメインのページとなるindex.htmlを見ていく。

  {% extends "layout.html" %}
  {% block content %}
  <div class="container">
    <div class="row">
      <div class="col-md-12">
        {% for hatebu in hatebu_array %}
          <div class="card mt-5">
            <div class="card-header">
              <h5 class="card-title">人気記事</h5>
            </div>
            <div class="card-body">
              <p class="card-text">{{ hatebu[0] }}</br>Users:{{ hatebu[2] }}</p>
              <a href="{{ hatebu[1]}}" class="btn btn-primary">Go Page</a>
            </div>
          </div>
        {% endfor %}
      </div>
    </div>
  </div>
  {% endblock %}

まずは{% extends “layout.html” %}でベースになるテンプレートを読み込んでいる。
次に、{% block content %}{% endblock %}の間にHTMLが書かれている。
この中身が先ほどのlayout.htmlのbody内にはめ込まれるのだ。

HTMLの中でPythonのfor文を動かして文字を表示させているが、今回はあくまでflaskの解説のため割愛。
また進んでいくにつれて、jinnja2でのPythonコードの書き方も解説する予定。

実行!

flaskのアプリを実行する。
前回はいろいろ面倒なコマンドを書いたが、今回はapp.pyをpythonで実行するだけで完了である。

  >python app.py

お詫び

今回から作業の環境が変わっている。
前回まではubuntuで行っていたが、今回からwindowsに変更した。
改めて、マシンスペックは以下の通りである。

PC:Surface Laptop
OS:Windows10Pro
CPU:intel i5(第七世代)
RAM:8GB

愛機のsurfaceにメインPCを戻した形。
浮気しててごめんね。

一応今回で簡単なアプリケーションができてしまったわけなので、次回はherokuにデプロイしてネット上に公開する方法を解説しようと思う。

前の記事:初心者のためのFlaskアプリ開発② FlaskでHelloWorldアプリをつくる