pythonで株価をスクレイピングする
前回Webページのスクレイピングまでできたので今回は株価のスクレイピングを試します。
株探のページ情報
URL
ソース(一部)
<div id="kobetsu_left"> <dl> <dt>前日終値</dt> <dd class="floatr">3,340.0 (<time datetime="2021-10-06">10/06</time>)</dd> </dl> <h2><time datetime="2021-10-07">10月07日</time></h2> <table> <tbody> <tr> <th scope="row">始値</th> <td>3,200.0</td> <td class="mark"> </td> <td>(<time datetime="2021-10-07T09:03+09:00">09:03</time>)</td> </tr> <tr> <th scope="row">高値</th> <td>3,245.0</td> <td class="mark"> </td> <td>(<time datetime="2021-10-07T14:52+09:00">14:52</time>)</td> </tr> <tr> <th scope="row">安値</th> <td>3,157.0</td> <td class="mark"> </td> <td>(<time datetime="2021-10-07T09:06+09:00">09:06</time>)</td> </tr> <tr> <th scope="row">終値</th> <td>3,221.0</td> <td class="mark"> </td> <td>(<time datetime="2021-10-07T15:00+09:00">15:00</time>)</td> </tr> </tbody> </table> ・ ・ ・ </div>
株探の解析
サンプルプログラム
import requests from bs4 import BeautifulSoup res = requests.get("https://kabutan.jp/stock/?code=4502") doc = BeautifulSoup(res.text, "html.parser") el = doc.select("#kobetsu_left tr") if el is not None: for row in el: print(row.select("td"))
selectメソッドにCSSセレクタ("#kobetsu_left tr")を指定して要素を取得します。
取得した要素の中からさらにselectメソッドにCSSセレクタ("td")を指定して取得した要素を出力してみます。
実行結果
[<td>3,200.0</td>, <td class="mark"> </td>, <td>(<time datetime="2021-10-07T09:03+09:00">09:03</time>)</td>] [<td>3,245.0</td>, <td class="mark"> </td>, <td>(<time datetime="2021-10-07T14:52+09:00">14:52</time>)</td>] [<td>3,157.0</td>, <td class="mark"> </td>, <td>(<time datetime="2021-10-07T09:06+09:00">09:06</time>)</td>] [<td>3,221.0</td>, <td class="mark"> </td>, <td>(<time datetime="2021-10-07T15:00+09:00">15:00</time>)</td>] ・ ・ ・ ・
株価部分を含んだ要素が取得できてますね。
この結果からさらに株価部分を取得できれば目的は達成できます。
サンプルプログラム
import requests from bs4 import BeautifulSoup res = requests.get("https://kabutan.jp/stock/?code=4502") doc = BeautifulSoup(res.text, "html.parser") el = doc.select("#kobetsu_left tr") if el is not None: print("始値" + el[0].select("td")[0].getText()) print("高値" + el[1].select("td")[0].getText()) print("安値" + el[2].select("td")[0].getText()) print("終値" + el[3].select("td")[0].getText())
保有中の株の株価を自動集計したいのでpythonでスクレイピングする方法を調査
保有中の株の株価を自動で取得してデータベース化したいのでpythonでスクレイピングする方法を調査しました。
requestsモジュール
最低限必要なのはrequestsモジュール
pipコマンドを使ってインストールします。
pip3 install requests
サンプルプログラム
scrape_html.py
import requests import json res = requests.get("http://sample.kansai-fan.com/py/pymysql.py") print(res.text)
requestsモジュールのgetメソッドで指定したURLのレスポンスを取得
レスポンスのtextプロパティを出力すればhtmlの内容が出力されます。
実行結果
<html><meta charset='utf-8'><body> <h1>PyMySQLサンプル</h1> 件数2 </body></html>
BeautifulSoupモジュール
次にやりたいのはhtmlから特定のデータを抽出すること。
これはBeautifulSoupモジュールを使えば簡単に実装できます。
こちらもpipコマンドを使ってインストールします。
pip3 install beautifulsoup4
サンプルプログラム
scrape_html.py
import requests import json from bs4 import BeautifulSoup res = requests.get("http://sample.kansai-fan.com/py/pymysql.py") doc = BeautifulSoup(res.text, "html.parser") el = doc.find("h1") if el is not None: print(el.get_text())
コンストラクタで取得したhtmlとパーサーを指定すれば解析は完了。
後はfindメソッドを使って要素を取得、get_text()メソッドで内容を表示させます。
実行結果
PyMySQLサンプル
<h1>の内容が出力されました。
findメソッドにタグを指定すると最初の要素のみ取得。
複数の要素を取得したいときはfind_allメソッドを使う必要があります。
これでスクレイピングの準備は完了。
次回は株価取得に挑戦する予定です。
スターサーバーでpythonからMySQLに接続できた!
前回はpythonで使えるMySQLライブラリを調べてみました。
結論から言うとmysql-connector-pythonとPyMySQLを使ってMySQLに接続してデータを取得することができました。
ライブラリのダウンロードと設置
アップロード後
動作確認用のテーブル
サンプルプログラム(mysql-connector-python)
mysqlconnector.py
#!/usr/bin/python3.6 import mysql.connector as mydb import sys, io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding = 'utf-8') connection = mydb.connect(host='aaa.bbb.ccc', port='3306', user='dbuser', password='dbpassword', database='db_sample', charset='utf8' ) cursor = connection.cursor() cursor.execute("select count(*) as cnt from sample1") cnt = 0 row = cursor.fetchone() if row is not None: cnt = row[0] cursor.close() connection.close print("Content-Type: text/html; charset=utf-8\n") print("<html><meta charset='utf-8'><body>") print("<h1>mysql-connector-pythonサンプル</h1>") print("件数" + str(cnt)) print("</body></html>")
サンプルプログラム(PyMySQL)
pymysql.py
#!/usr/bin/python3.6 import pymysql import pymysql.cursors import sys, io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding = 'utf-8') # コネクションの作成 connection = pymysql.connect(host='aaa.bbb.ccc', user='dbuser', port=3306, password='dbpassword', db='db_sample', charset='utf8', cursorclass=pymysql.cursors.DictCursor) cursor = connection.cursor() cursor.execute("select count(*) as cnt from sample1") cnt = 0 row = cursor.fetchone() if row is not None: cnt = row["cnt"] print("Content-Type: text/html; charset=utf-8\n") print("<html><meta charset='utf-8'><body>") print("<h1>PyMySQLサンプル</h1>") print("件数" + str(cnt)) print("</body></html>")
コネクション関連の設定はmysql-connector-pythonとほぼ同じ。
ポートの指定が数値型なのとcursorclassにpymysql.cursors.DictCursorを指定することにより結果を辞書型で返してくれます。
実行結果
件数がちゃんと出力されました。
これでスターサーバーでpythonとMySQLを使ってWebアプリを作る環境が整いました。
スターサーバーでpythonからMySQLに接続するのは無理なのか?
Bottleのルーティング機能を試す
スターサーバーでBottleを使ったページを表示させることができました。
今回は動的ルーティングを試しました。
サンプルプログラム
index.py
#!/usr/bin/python3.6 from bottle import route, run, template @route('/') def index(): return template("sample", name="テスト") ※ @route('/<name>') def test(name): return template("sample", name=name) run(server='cgi')
※ ルートディレクトリ/xxxにアクセスするとtest(name)が実行され、引数のnameにはxxxが設定される
sample.html
<html lang="ja"> <head> <title>サンプル</title> </head> <body> {{ name }} </body> </html>
これで/xxxにアクセスすると画面上にxxxが表示されるはずなのですが・・・
404エラーになりました。
index.pyにアクセスできていないようですね。
下記のようにURLを変更すれば表示されるようになりました。
/index.py/xxx
日本語も大丈夫
/index.py/テスト
しかしできるならドキュメントルート+ "/xxx"でちゃんと表示されるようにしたいですね。
.htaccessに下記を追加してURLをリライトするようにします。
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.py$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.py/%{REQUEST_URI} [L] </IfModule>
/xxxにアクセスするとURLの表示内容は変わらないけど裏では /index.py/xxxにアクセスするようになります。
.htaccessを更新して/xxxにアクセスすると
表示されました。
index.pyをコントローラにすれば動的なページの作成も簡単に実装できそうです。