追記(2018/08/15)
ソースコードの全体像を載せてなかったので、Githubのリポジトリを公開しておきます。
拙いコードで恥ずかしいですが、記録として残しておきます。
https://github.com/alumi-mic/flasksample-hatebu
今回はFlaskアプリケーションでテンプレートビューを使用してページを表示するところまで実践します。
前回の記事:初心者のためのFlaskアプリ開発② FlaskでHelloWorldアプリをつくる
本記事の構成
この記事の構成は以下の通り。
今回作成するアプリケーションのファイル構成
今回作成するファイル構成は以下の通りです。
前回作成した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.h2 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のアプリを実行します。
前回はいろいろ面倒なコマンドを書きましたが、今回はapp.pyをpythonで実行するだけで完了です。
>python app.py
一応今回で簡単なアプリケーションができてしまったわけなので、次回はherokuにデプロイしてネット上に公開する方法を解説しようと思います。
time.pyではなくapp.pyですね。
とても役に立ちました。ありがとうございます!