Python学習【365日チャレンジ!】343日目のマスターU(@Udemy11)です。
近くの川の河口でヒラメが釣れているという情報をキャッチしたので、気合を入れて早朝から釣りに行ってきました。
現場に到着すると、結構人が等間隔で釣っていたのですが、かなり広い場所なので、ランガンしながらルアーを投げ続けました。
日が上がって、11時くらいまで投げ倒したのですが、残念ながら、アタリの一つもありませんでした。
私が見える範囲では釣れている人もいなかったので、情報がデマだったのか、広大な範囲なので、ピンポイントで釣れている場所があるのかのどちらかだったのかもしれません。
最近釣りにも行ってなかったので、いい運動にはなりました。
それでは今日も、Python学習を始めましょう。
昨日の復習
昨日は、検索キーワードを入力して、入力されたキーワードで検索した結果のページからURLとタイトルを抽出してみました。
コードはいたって簡単で、search_query
をinput()
に変更するだけでした。
あまりにも簡単だったので、以前から気になっていたタイトルが文字化けを起こす問題を解決するためにいろいろ調べてみたところ、なんとか解決することができました。
詳細についてはこちらの記事をごらんください。
今日は、Tkinter
を使って、入力ウインドウを表示して、テキスト入力窓に入れたキーワードでGoogle検索した結果ページからURLとタイトルを抜き出してCSVに保存するプログラムを作りたいと思います。
インターフェイス
作成する入力ウインドウはこんな感じ
それではTkinterを使って入力ウインドウを作成していきましょう。
Tkinterについては、以前学習したこのあたりの記事が参考になるかと思います。
getut_data.py
入力ウインドウの設定は、ファイル名をgetut_data.py
にしてコードを書いていきます。
import tkinter as tk
import scrape_t_u
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master.geometry()
self.master.title('Get URL and TITLE')
self.entry = tk.Entry(self.master,width=40)
self.menu_bar = tk.Menu(self.master)
self.master.config(menu=self.menu_bar)
self.create_widgets()
def clear_all(self):
self.entry.delete(0, tk.END)
def search(self):
keywords = self.entry.get()
scrape_t_u.main(keywords)
def create_widgets(self):
file_menu = tk.Menu(self.menu_bar)
file_menu.add_command(label='Exit', command=self.master.quit)
self.menu_bar.add_cascade(label='File', menu=file_menu)
self.entry.grid(row=1, column=1, columnspan=6, pady=10, padx=10)
self.entry.focus_set()
tk.Button(self.master, text='Clear', width=4,
command=lambda: self.clear_all()).grid(row=2, column=5)
tk.Button(self.master, text='抽出', width=4,
command=self.search).grid(row=2, column=6, pady=10)
root = tk.Tk()
app = Application(master=root)
app.mainloop()
コードが長いので、パーツに分けて見ていきましょう。
インポートするライブラリ
import tkinter as tk
import scrape_t_u
インポートするライブラリは、tkinter
で、scrape_t_u
は、これまでに作成したgoogle検索の結果ページからURLとタイトルをCSVに書き出すファイル(モジュール)です。
フレームの作成
class Application(tk.Frame):
続いて、tk.Frame
を継承したApplication
クラスを作成します。
次にクラス内で設定する初期化や関数のコードを定義しています。
初期化
最初は、オブジェクトを生成したときの初期化(__init__
です。
def __init__(self, master=None):
super().__init__(master)
self.master.geometry()
self.master.title('Get URL and TITLE')
self.entry = tk.Entry(self.master, width=40)
self.menu_bar = tk.Menu(self.master)
self.master.config(menu=self.menu_bar)
self.create_widgets()
コードの最後に記述していますが、Application
オブジェクトを生成するときに引き渡す引数のmaster
のデフォルト値をNone
にして、super().__init__(master)
でオーバーライドしていますが、このコードはtkinter
のテンプレートのようなものです。
7行目のself.master.geometry()
は、作成するボタンや入力枠の配置を細かく指定するためのものです。
8行目は、入力ウインドウのタイトルをGet URL and TITLE
に指定しています。
10行目は、入力枠の幅を指定してself.entry
として作成しています。
12行目と13行目では、メニューバーに表示するためのself.menu_bar
を生成して、self.master.config
に指定しています。
15行目で、後で解説する入力ウインドウを設定する関数のcreate_widgets()
を実行します。
必要な関数
続いて、入力ウインドウに配置する入力枠の入力を消去するボタンと、Google検索からURLとタイトルをCSVに書き出すモジュールを実行するボタンの関数を定義します。
def clear_all(self):
self.entry.delete(0, tk.END)
def search(self):
keywords = self.entry.get()
scrape_t_u.main(keywords)
17行目のclear_all
はその名のとおり、18行目で入力枠に入力された文字を消去します。
delete(0, tk.END)
は、入力枠の最初の文字から最後の文字までを消去するコードですね。
20行目のsearch()
は、21行目のself.entry.get()
で入力枠に入力された値を取得して、keywords
に代入して、インポートしたモジュール(scrape_t_u.py
のmain()
の引数にkeywords
を代入して実行するコードです。
ウィジットのレイアウトと動作
def create_widgets(self):
file_menu = tk.Menu(self.menu_bar)
file_menu.add_command(label='Exit', command=self.master.quit)
self.menu_bar.add_cascade(label='File', menu=file_menu)
self.entry.grid(row=1, column=1, columnspan=6, pady=10, padx=10)
self.entry.focus_set()
tk.Button(self.master, text='Clear', width=4,
command=self.clear_all).grid(row=2, column=5)
tk.Button(self.master, text='抽出', width=4,
command=self.search).grid(row=2, column=6, pady=10)
create_widgets()
は、ウィジット(入力ウインドウ)のレイアウトとボタン等の実行コマンドの設定です。
25行目で、初期化で設定したmenu_bar
を使ってfile_menu
を作ります。
次に26行目で、そのメニューにExit
と表示され、クリックでアプリを終了するコマンドを指定します。
27行目で、file_menu
のラベルをFile
と表示させています。
28行目で入力枠の表示位置を指定して、29行目で入力ウインドウを表示した際に入力枠に入力できるようにしています。
30行目・31行目で、入力枠に入力した文字を消去するボタンを作成していますが、表示する文字がClear
で、実行するコマンドは、先程定義した関数clear_all
を指定し、grid
で位置を決めています。
33行目・34行目はClear
ボタンと同じように、抽出したURLとタイトルをCSVに書き出すボタンを作成しています。
表示される文字は抽出
で、実行コマンドには関数search
を指定して、grid
で位置を決めています。
ファイルの実行
root = tk.Tk()
app = Application(master=root)
app.mainloop()
最後は、クラスからインスタンスを生成してmainloop()
でアプリを終了するまでプログラムを待機させる状態にします。
mainloop()
はこちらの記事がわかりやすく解説されていますので、参考にどうぞ
コードに戻りますが、37行目でトップレベルのウィジットであるTk
をインスタンス化したroot
を作り、38行目でApplication
の引数master
にroot
を入れてapp
インスタンスを生成したあと、mainloop()
でアプリを立ち上げています。
これで、Tkinterで作るインターフェイスは完成で、目標にしていた次の入力ウインドウにコマンドを紐付けたウィジットが完成します。
次に、抽出
ボタンをクリックしたときに実行するモジュールであるscrape_u_t.py
をチェックしましょうと行きたいところですが、少し長くなってしまったので、明日に持ち越したいと思います。
まとめ
入力ウインドウを作るにあたって、Tkinterのレクチャーで学習した計算機のコードをかなり参考にしました。
必要なコード、不必要なコードを精査しながら今回のコードを書きましたが、たくさんコードを書いて経験を積むことの重要性がひしひしと感じられました。
ほんと書けば書くほど、何がどうなっているのかわかってくるのですが、これは経験してみないことにはわかりません。
例えば、エクセルで計算式を入れているのに、計算結果が表示されないときは、設定オプションで自動計算がオフになっている可能性が考えられますが、何度も経験しているからわかることで、エクセルを使い慣れていない人はなかなか原因を突き止めることができません。
Pythonも同じように、たくさんのコードを書いて経験しておけば、エラーが起こっている原因がわかったり、トラブルに対応できるようになるので、Pythonマスターになるには、コードをたくさん書いて経験を積むしかありません。
Webスクレイピングは、これまでもやりたいと思っていたことなので、コードを書くのが楽しいので、いろいろと試しながら、どんどんコードを書いていきたいとおもいます。
それでは、明日もGood Python!